- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我知道在 Base 类的构造函数中 - 当调用虚拟方法时 - 调用 Base 方法,而不是派生 - 参见 Calling virtual functions inside constructors .
我的问题与这个主题有关。我只是想知道如果我在 Derived 类构造函数中调用虚拟方法会发生什么 - 但在构造 Base 部分之前。我的意思是调用虚方法来评估基类构造函数参数,请参见代码:
class Base {
public:
Base(const char* name) : name(name) {
cout << "Base():" << name << endl;
}
virtual const char* getName() {
cout << "Base::getName()" << endl;
return "Base";
}
protected:
const char* name;
};
class Derived : public Base {
public:
Derived() : Base(getName()) {
cout << "Derived():" << name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return "Derived";
}
};
int main() {
Derived d;
}
编译器 g++(4.3.x-4.5x 版本)输出为:
Derived::getName()
Base():Derived
Derived():Derived
不过我希望:
Base::getName()
Base():Base
Derived():Base
这看起来没有错 - 但请考虑这个产生段错误
的例子:
class Derived : public Base {
public:
Derived() : Base(getName()), name(new string("Derived")) {
cout << "Derived():" << Base::name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return name->c_str();
}
private:
string* name;
};
请回答:这是正确的 g++ 行为吗? C++ 标准对此有何规定?也许这是未定义的行为?
[更新1]我考虑了罗伯特和奥利的回答——我改变了我的第一个例子。然后它 getName() 被称为“虚拟” - 它会产生段错误。请也回答我对这部分的问题。
const char* virtualGetName(Base* basePtr)
{
return basePtr->getName();
}
class Derived : public Base {
public:
Derived() : Base(virtualGetName(this)) {
cout << "Derived():" << Base::name << endl;
}
virtual const char* getName() {
cout << "Derived::getName()" << endl;
return "Derived";
}
};
最佳答案
您的所有示例都表现出未定义的行为。 C++ 语言标准声明 (C++11 §12.6.2/13):
Member functions (including virtual member functions) can be called for an object under construction. Similarly, an object under construction can be the operand of the
typeid
operator or of adynamic_cast
.However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined.
您正在从 Derived
类构造函数的初始化列表(ctor-initializer)中调用成员函数 getName()
。此成员函数调用必须在 Base
的初始化程序完成之前发生(Base
的 mem-initializer),因为它是初始化程序的参数本身。
因此,行为是未定义的。
通常,Never Call Virtual Functions during Construction or Destruction .
关于c++ - 这是正确的 : virtual method of Derived called before constructing Base object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11335525/
我在 Ubuntu 11.10 和最新版本的 NetBeans 下使用 C++。假设我有以下代码: class Node {} class DerivedNode : public Node {} c
这两者在 GHC 中有什么区别。它们的预期用途似乎相似,但 deriving (Data)已经存在了一段时间了deriving (Generic)最近才添加到 GHC 中。 是 deriving (G
当您将矩阵对象作为 MatrixBase 引用传递给函数时会发生什么?我不明白幕后到底发生了什么。 示例函数代码如下: #include #include using namspace Eigen
我正在尝试了解如何在 Eigen 中使用样条曲线,特别是我想在某个点上找到样条插值及其一阶和二阶导数的值。找到内插值很容易,但是当我尝试计算导数时,我得到了奇怪的值。 我尝试按照手册 ( http:/
使用 C++ Builder XE7 我有一个带有 TImageList 对象的基本表单 object FormBase: TFormBase Left = 0 Top = 0 Capti
我正在制作基类和派生类。派生类的值将为 Eigen::Matrix , 并继承了 Base 的所有方法。 我这样做是为了使无论矩阵类型如何都相同的方法不会因为 Matrix 的不同模板参数而全部重复。
我最近更新到最新的 Eigen 版本 (3.3.90),看起来它破坏了我之前工作的东西(在我使用 libigl 库附带的 Eigen 版本 3.2.10 之前)。 我想将 block 的结果存储到一个
我最近一直在尝试“向我学习 Haskell”,我想创建一个新类型来表示整数状态,而不仅仅是使用原始 Integer(为了类型安全和代码清晰)。具体来说,以下代码编译: newtype AuxState
这个问题已经有答案了: Access subclass fields from a base class in Java (4 个回答) 已关闭 4 年前。 我对 Java 和面向对象编程总体来说是新
我有这些类,事件记录模式的实现: public abstract class RecordCollection : ObservableCollection where T : Record publ
首先,这个问题非常类似于 downcasting shared pointer to derived class with additional functionality is ,哪里有好的答案。但
好的,我正在通读 this entry in the FQA处理将 Derived** 转换为 Base** 的问题以及为什么它被禁止,我得到的问题是你可以分配给 Base* 不是 Derived*
我正在使用 Boost.Python 将我的 C++ 代码公开给 Python。我遇到了与将对象从一种语言多次传递到另一种语言有关的困难。这是我想要做的: C++代码 class Base { p
这个问题在这里已经有了答案: Downcasting using the 'static_cast' in C++ (3 个答案) 关闭 8 年前。 我不明白为什么会这样。pReallyABase
https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial 的问题 7 “找到每个大陆中最大的国家(按面积),显示大陆、名称和面积:” 我不明白为什么
我很难理解为什么以下代码无法编译: template class Base { public: Base(int a){} }; template class Derive
我很难理解为什么以下代码无法编译: template class Base { public: Base(int a){} }; template class Derive
Base to Derived 是可能的(装箱)。但是 Derived to base 给出了运行时异常,然而这相当于拆箱。为什么会这样 Base b = new Base(); Child c =
库代码 我的图书馆有一个 CRTP 类 B . 我创建了一个 Trait使用户能够更改 B 行为的类. 默认设置为 int . ( #1 ) #include #include //B and T
我正在学习 C++ 继承,所以我通过动态创建一个 Base 类来尝试这段代码,并对它的 Derived 类进行向下转换(显然向下转换无效)以使这个动态创建的 Base 对象被指向派生类指针。但是当我通
我是一名优秀的程序员,十分优秀!