草庐IT

C++ 等效于类属性的 Matlab 抽象

coder 2024-02-24 原文

简短版:
考虑以下伪代码:

class Foo {
    private:
        abstract type myVar;
} // This class is abstract

您将如何在标准 C++ 中实现此行为?


长版:
我必须将大量面向对象的代码从 Matlab 移植到 C++。 请注意,我是世界上使用 Matlab 经验最少的人,自 2007 年以来我就不再使用 C++。

我在谷歌上搜索了很多关于这个主题的内容,但找不到正确的答案来解决我的问题。 所以我在这里 :)

假设您有这个 matlab 类:

classdef Foo < handle
    properties (Abstract, Dependent)
        A
    end

    properties
        B
    end

    methods (Abstract)
        computeA()
    end

    methods (Access = protected)
        function obj = Foo(bar)
            obj.B = Matlab.BlaBlaBla(bar)
    end
end

这个类(我想)不能“直接”分配,因为它的构造函数是 protected 。 属性“A”也是抽象的(暂时忽略也是从属的事实)。 MathWorks 告诉我们,这意味着:

  • 具体子类必须重新定义抽象属性,而无需 抽象属性,并且必须对 SetAccess 和 GetAccess 属性与抽象父类(super class)中使用的属性相同。
  • 抽象属性不能定义 set 或 get 访问方法(参见 属性访问方法)并且不能指定初始值。这 定义具体属性的子类可以创建 set 或 get 访问方法并指定初始值。

那么您如何在 C++ 中正确翻译此类行为? 如果我这样做是对的吗? (我的意思是,这不是一个糟糕的设计实践)

class Foo {
    private:
         type A;
         type B;
    protected:
         virtual void computeA() = 0;
         Foo(type bar) { this.B = SomeFoo(bar); }
}

我的想法(我可能是错的)是,如果我这样做,人们将不得不这样做

class Subclass: Foo {
    protected:
        void computeA(){...} 
    public:
        type A() { computeA(); return A; } //This is A getter that grants Dependent behavior
}

否则会在编译时出错。

我错了吗?有更好的方法吗? 也是翻译 Dependent 关键字的正确方法吗?

最佳答案

首先,我认为重要的是要问:一个类的公共(public)接口(interface)是什么(它的职责是什么,它如何与其他人交互)?

根据您的 Matlab 代码,答案是:该类定义了属性 A 和 B 以及方法 computeA。根据我对依赖属性的理解,我怀疑 computeA() 应该是公开的(参见 Matlab docs )。如果您的其余代码需要它,您当然可以将其公开,但我会尽量减少可访问性。

现在 C++ 中不存在 Property 的概念。 Matlab 的有趣之处在于基类决定是否有 A.get、A.set 或两者以及可访问性。我不知道这背后的原理,但在我看来似乎没有太大意义。在 C++ 中,我会将属性转换为获取/设置方法。参见 this question用于讨论在 C++ 中实现这些。根据您的选择,您可以将非依赖属性实现为成员对象或 get/set 方法。

一旦您定义了方法的公共(public)接口(interface),我就会开始考虑如何实现它。请注意,Matlab 和 C++ 的内存管理是不同的(Matlab 使用 Copy on Write 并关心内存管理,这些在纯 C++ 中都不存在)。此外,在(慢速面向对象的)Matlab 代码中可能需要缓存值(如对 computeA 和依赖属性所做的那样),但在 C++ 中则不一定。为避免过早优化,为什么不这样做:

class Foo {
    public:
      ClassB B;
      virtual ClassA getA() = 0;
      //define a setA()=0 if you need it here
    protected:
         //I wouldn't force subclasses to have the "caching" of dependent properties, so no virtual void computeA() = 0; 
         Foo(ClassBar const& bar) { this.B = ClassB(bar); /*Note that SomeFoo cannot be assigned to B*/ }
}
class Subclass: public Foo {
    private:
        ClassA A;
    public:
        ClassA getA() { ClassA A; /*compute A*/ return A; } 
}

如果你觉得A的计算速度太慢,你仍然可以在子类中“本地缓存A”:

class Subclass: public Foo {
    private:
        ClassA A;
    public:
        ClassA getA() { /*compute A if required*/ return A; } 
}

如果您真的想将 A 存储在 Foo 中,我宁愿将其实现为

class Foo {
    private:
      ClassA A;
    public:
      ClassB B;
      ClassA getA() { if (!A.initialized) A=computeA(); return A; };
    protected:
         virtual ClassA computeA() = 0;
         Foo(ClassBar const& bar) { this.B = ClassB(bar); /*Note that SomeFoo cannot be assigned to B*/ }
}
class Subclass: public Foo {
    protected:             
         virtual ClassA computeA() {...}
}

并且不要忘记始终考虑您是否真的想传递(常量)引用或值...

关于C++ 等效于类属性的 Matlab 抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14359330/

有关C++ 等效于类属性的 Matlab 抽象的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  5. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  6. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  7. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  8. Matlab imread()读到了什么 (浅显 当复习文档了) - 2

    matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1

  9. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  10. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

随机推荐