类似于: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/