c++ - OOP - 抽象类类型,在基类和派生类中初始化变量

标签 c++ inheritance abstract-class

类似于:How can I initialize base class member variables in derived class constructor? ,但我想知道为什么如果我有:

class A {
public:
    A(int val);
    virtual int get_val() = 0;
protected:
    int val;
};

class B : public A {
public:
    B(int val, int extra);
    int get_val() = 0;
private:
    int extra;
};

我想知道这样做有什么区别:

A::A(int val) : val(val) {}

和:

A::A(int val) {val = val;}

还有为什么,当我在类 B 的构造函数中时,我不能这样做:

B::B(int b, int extra) : A(b) {
    extra = extra;
}

但我能做到:

B::B(int b, int extra) : A(b) {
    this->extra = extra;
}

或者,

B::B(int b, int extra) : A(b), extra(extra){}

将 extra 的值存储在 B 中。如果我不这样做,它就不会被存储。我很困惑发生了什么。

最佳答案

I'm wondering what is the difference between doing this:

A::A(int val) : val(val) {}

and:

A::A(int val) {val = val;}

第一个是对的,第二个是错的。

更准确地说,第一个用构造函数参数 val 的值初始化数据成员 A::val,毫无疑问,这正是您想要的做。

相比之下,第二个对 A::val 不做任何事情,留下一个未初始化的值,这将在您尝试从数据成员读取时立即导致未定义的行为。 val = val; 行将构造函数参数 val 赋值给自己,这完全没有意义。

如果您使用不同的参数名称来消除歧义,第二个就可以了,例如:

A::A(int new_val) { val = new_val; }

如果你喜欢在你自己的 this->extra = extra; 示例中,它也可以正常工作:

A::A(int val) { this->val = val; }

在这两种情况下,编译器现在都知道您指的是 A::val

但是,这种构造函数实现形式在 C++ 中并不典型,通常是 Java 或 C# 程序员的标志。它使 A::val 暂时未初始化,然后为其分配一个值。那只是不太合逻辑。如果可以的话,为什么不立即初始化它呢?它也不适用于 const 成员、引用成员或没有默认构造函数或稍后分配内容的方法的数据类型。

顺便说一句,这与效率无关,只与正确性和可读性有关。

关于c++ - OOP - 抽象类类型,在基类和派生类中初始化变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49842411/

相关文章:

c++ - 将复杂数据从主机传输到设备的简单 CUDA 代码问题

c++ - 模板基类的子类的模板特化

swift 如何定义抽象类以及为什么苹果发明关联类型但不使用通用协议(protocol)

c++ - Visual Studio 中的错误 : No symbols loaded for opencv_world310. dll

c++ - Qt Creator 在 Mac 上启动调试失败

C++ 抽象基模板类非 Void 方法

java - 使用泛型和反射时出现不兼容类型错误

c++ - 非公共(public) C++ 继承在实践中的使用频率是多少?

android - 如何在android中为这个coverflow应用程序实现onItemClickListener

java - 抽象类的公共(public)构造函数是否有充分的理由