为什么c++没有虚构造函数?
当前回答
总结:c++标准可以为“虚拟构造函数”指定一种表示法和行为,这是相当直观的,而且编译器也不难支持,但是为什么在已经可以使用create() / clone()清晰地实现功能的情况下(见下文),还要专门为此做出标准更改呢?它远不如正在酝酿中的许多其他语言提案那么有用。
讨论
让我们假设一个“虚拟构造函数”机制:
Base* p = new Derived(...);
Base* p2 = new p->Base(); // possible syntax???
在上面的代码中,第一行构造了一个Derived对象,因此*p的虚拟调度表可以合理地为第二行提供一个“虚拟构造函数”。(本页上有几十个回答说“这个物体还不存在,所以虚拟构建是不可能的”,这些答案都是不必要的短视地关注即将被构建的物体。)
第二行假设符号new p->Base()请求动态分配和另一个派生对象的默认构造。
注:
the compiler must orchestrate memory allocation before calling the constructor - constructors normally support automatic (informally "stack") allocation, static (for global/namespace scope and class-/function-static objects), and dynamic (informally "heap") when new is used the size of object to be constructed by p->Base() can't generally be known at compile-time, so dynamic allocation is the only approach that makes sense it is possible to allocate runtime-specified amounts of memory on the stack - e.g. GCC's variable-length array extension, alloca() - but leads to significant inefficiencies and complexities (e.g. here and here respectively) for dynamic allocation it must return a pointer so memory can be deleted later. the postulated notation explicitly lists new to emphasise dynamic allocation and the pointer result type.
编译器需要:
通过调用隐式的虚拟sizeof函数或通过RTTI获得这些信息,找出Derived需要多少内存 调用operator new(size_t)来分配内存 调用Derived(),位置为new。
OR
为结合了动态分配和构造的函数创建额外的虚表项
因此,指定和实现虚拟构造函数似乎并不是不可克服的,但最重要的问题是:它如何比使用现有的c++语言特性更好?就我个人而言,我认为下面的解决方案没有任何好处。
' clone() '和' create() '
c++常见问题解答文档中记录了一个“虚拟构造函数”习语,包含了用于默认构造或复制构造一个新的动态分配对象的虚拟create()和clone()方法:
class Shape {
public:
virtual ~Shape() { } // A virtual destructor
virtual void draw() = 0; // A pure virtual function
virtual void move() = 0;
// ...
virtual Shape* clone() const = 0; // Uses the copy constructor
virtual Shape* create() const = 0; // Uses the default constructor
};
class Circle : public Shape {
public:
Circle* clone() const; // Covariant Return Types; see below
Circle* create() const; // Covariant Return Types; see below
// ...
};
Circle* Circle::clone() const { return new Circle(*this); }
Circle* Circle::create() const { return new Circle(); }
也可以更改或重载create()以接受参数,不过为了匹配基类/接口的虚函数签名,重写的参数必须精确匹配基类重载中的一个。有了这些用户提供的显式功能,添加日志记录、检测、更改内存分配等就变得很容易了。
其他回答
虚函数用于根据指针所指向的对象类型调用函数,而不是指针本身的类型。但是构造函数不会被“调用”。它只在声明对象时调用一次。因此,在c++中构造函数不能被设为虚函数。
c++中的虚函数是运行时多态性的一种实现,它们将执行函数覆盖。在c++中,当需要动态行为时,通常使用virtual关键字。只有当对象存在时,它才会工作。而构造函数用于创建对象。构造函数将在对象创建时调用。
因此,如果您将构造函数创建为virtual,根据virtual关键字定义,它应该有现有的对象可以使用,但构造函数用于创建对象,因此这种情况将永远不存在。所以你不应该将构造函数作为虚函数使用。
因此,如果我们试图声明虚拟构造函数编译器抛出一个错误:
构造函数不能声明为虚函数
我能想到两个原因:
技术原因
对象只有在构造函数结束后才存在。为了使用虚拟表分派构造函数,必须有一个现有的对象和指向虚拟表的指针,但是如果对象仍然不存在,指向虚拟表的指针怎么可能存在呢?:)
逻辑的原因
当您想要声明某种多态行为时,可以使用virtual关键字。但是构造函数没有任何多态性,c++中的构造函数只是简单地将对象数据放到内存中。由于虚表(以及一般的多态性)都是关于多态行为而不是多态数据的,因此声明虚构造函数没有任何意义。
面试答案是:virtual ptr和table是和对象相关的,而不是和类相关的。因此构造函数构建虚表 因此,我们不能有虚构造函数,因为在创建obj之前没有虚表。
在创建对象时创建Vpointer。创建对象前Vpointer不存在。因此,没有必要将构造函数设为虚函数。
推荐文章
- 如何构建和使用谷歌TensorFlow c++ api
- 实例属性attribute_name定义在__init__之外
- 断言是邪恶的吗?
- 下面这些短语在c++中是什么意思:0 -,default-和value-initialization?
- 在STL地图中,使用map::insert比[]更好吗?
- C++ Linux的想法?
- 如何为Fedora安装g++ ?
- Std::cin输入空格?
- c++标准是否要求iostreams的性能很差,或者我只是在处理一个糟糕的实现?
- gcc在哪里查找C和c++头文件?
- 为什么我们需要require require ?
- 具有构造签名的接口如何工作?
- 解析c++中的命令行参数?
- 我如何在c++中创建一个随机的字母数字字符串?
- c++中的atan和atan2有什么区别?