matlab 类 属性,C等价于Matlab Abstract的类属性

精简版:

考虑以下伪代码:

class Foo {

private:

abstract type myVar;

} // This class is abstract

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

长版:

我必须将很多面向Obj的代码从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

这个类(我想)不能“直接”分配,因为它的构造函数是受保护的.

属性“A”也是抽象(暂时忽略了也是Dependent的事实).

MathWorks告诉我们,这意味着:

>具体的子类必须在没有的情况下重新定义抽象属性

抽象属性,必须使用相同的值为SetAccess和

GetAccess属性与抽象超类中使用的属性相同.

>抽象属性无法定义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关键字也是正确的方法吗?

最佳答案 首先,我认为重要的是要问:一个类的公共接口是什么(它的职责是什么,它与其他人的交互方式)?

从您的Matlab代码中,答案是:类定义属性A和B以及方法computeA.根据我对Dependent属性的理解,我怀疑computeA()应该是公共的(参见Matlab docs).如果您的其余代码需要这个,当然您可以将其公开,但我会尝试减少可访问性.

现在,C中不存在属性的概念.关于Matlab的有趣之处在于基类决定是否存在A.get,A.set或两者以及可访问性.我不知道背后的理由,但在我眼里似乎并没有多大意义.在C中,我会将属性转换为get / set方法.有关在C中实现这些内容的讨论,请参见this question.根据您的选择,您可以将非依赖属性实现为成员对象或get / set方法.

一旦定义了方法的公共接口,我就会开始考虑如何实现它.请注意,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中存储A,我宁愿把它实现为

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() {...}

}

并且不要忘记始终考虑您是否确实要通过(const)引用或值…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值