为什么c++没有虚构造函数?
当前回答
虚函数用于根据指针所指向的对象类型调用函数,而不是指针本身的类型。但是构造函数不会被“调用”。它只在声明对象时调用一次。因此,在c++中构造函数不能被设为虚函数。
其他回答
你也不应该在构造函数中调用虚函数。参见:http://www.artima.com/cppsource/nevercall.html
另外,我不确定是否真的需要虚拟构造函数。你可以在没有它的情况下实现多态构造:你可以编写一个函数,根据所需的参数构造你的对象。
A virtual-table(vtable) is made for each Class having one or more 'virtual-functions'. Whenever an Object is created of such class, it contains a 'virtual-pointer' which points to the base of corresponding vtable. Whenever there is a virtual function call, the vtable is used to resolve to the function address. Constructor can not be virtual, because when constructor of a class is executed there is no vtable in the memory, means no virtual pointer defined yet. Hence the constructor should always be non-virtual.
我们不能简单地说…我们不能继承构造函数。因此没有必要将它们声明为虚拟的,因为虚拟提供了多态性。
If you think logically about how constructors work and what the meaning/usage of a virtual function is in C++ then you will realise that a virtual constructor would be meaningless in C++. Declaring something virtual in C++ means that it can be overridden by a sub-class of the current class, however the constructor is called when the objected is created, at that time you cannot be creating a sub-class of the class, you must be creating the class so there would never be any need to declare a constructor virtual.
另一个原因是,构造函数的名字与其类名相同如果我们将构造函数声明为virtual,那么它应该在它的派生类中以相同的名字重新定义,但两个类的名字不能相同。所以不可能有一个虚拟构造函数。
总结: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()以接受参数,不过为了匹配基类/接口的虚函数签名,重写的参数必须精确匹配基类重载中的一个。有了这些用户提供的显式功能,添加日志记录、检测、更改内存分配等就变得很容易了。
推荐文章
- 如何构建和使用谷歌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有什么区别?