编辑:
这个问题作为一个骗局被关闭了。
我认为这显然不是骗局。
它处理与(假定的)原始 OP (OOP!) 相同的情况,但它提出了不同的问题。
更具体地说,OOP 的许多答案中的大多数都在处理为什么会发生这种情况,而我并没有问这个问题。而且我没有看到问题 Q1 和 Q2 的答案。
我的问题 Q3(加号)询问替代方案。
This 和 this 在 OOP 中提供替代方案。
如果有人想在这里添加其他人,那是欢迎的。
如果考虑将此 OP 标记为欺骗的原因,我可以删除 Q3。
我有以下代码
标题
a.h
class Bbase1 {
public:
Bbase1(int argsB) : _iB(argsB) {
// Do a lot of stuff, compute argsm
double argsm = 2 * argsB; // as an example
// NEED TO USE m(argsm). Use something different for testing purposes
_iB = m(double(_iB));
// Do another lot of stuff
};
virtual ~Bbase1() {};
public:
virtual int m(double argsm) = 0; // Set 2 // pure virtual called from constructor
virtual int m(double argsm) { return 10 * int(argsm); } // Set 1a
virtual void print() { std::cout << "_iB = " << _iB << std::endl; }
private:
int _iB;
};
class Bderived1 : public Bbase1 {
public:
Bderived1(int argsB) : Bbase1(argsB) {};
virtual ~Bderived1() {};
public:
virtual int m(double argsm) { return 100 * int(argsm); }
};
来源
Bbase1 Bb1(1); // Set 1b
Bderived1 Bd1(2);
cout << "Base: "; // Set 1b
Bb1.print(); // Set 1b
cout << "Derived: ";
Bd1.print();
我需要在基(抽象)类
m
的构造函数中调用一个纯虚方法Bbase1
。
在这些条件下,Set 1a,1b(见代码中的注释)将被注释。
那不会链接,预计会抛出链接错误undefined reference to 'Bbase1::m(double)'
。
另外,还有一个编译警告pure virtual 'virtual int Bbase1::m(double)' called from constructor
.
OTOH,如果我设法将
m
转换为非纯,注释 Set 2,代码编译、链接和运行。
但是 Bderived1
的构造函数仍然会使用 Bbase1::m
。
Bbase1::m
也是真的吗? (可能是最不常见的情况)。在这种情况下会有什么危险?
我放在一起的解决方法(对应于这里和那里的描述)是用
替换构造函数Bbase1(int argsB) : _iB(argsB) {};
// move here the exact contents of the non-working constructor
virtual void Bbase1Constr(int argsB) {
// Do a lot of stuff, compute argsm
double argsm = 2 * argsB; // as an example
// NEED TO USE m(argsm). Use something different for testing purposes
_iB = m(double(_iB));
// Do another lot of stuff
};
并且在源代码中总是将两者一起使用
Bderived1 Bd1(2);
Bd1.Bbase1Constr(2);
到目前为止,我发现这完全涵盖了目标。 我的其他问题是: