在下面的代码中,我不确定为什么 C++ 允许在 Child 虚拟显示定义中使用纯虚拟方法默认值。为什么编译器允许这样做?使用构造函数和向上转换的静态成员初始化是否需要额外的规则来允许它?
#include <iostream>
struct Parent {
const char* name;
size_t size;
Parent(const char* name, size_t size) : name{name}, size{size} {}
virtual ~Parent() {}
virtual void show(const std::string *obj, int level = 0) const = 0;
};
struct Child : Parent {
Child(void (*init)(Child*)) : Parent{nullptr, 0} {
init(this);
}
virtual void show(const std::string *obj, int level) const override{
std::cout << "name = " << name << std::endl;
std::cout << "size = " << size << std::endl;
std::cout << "level = " << level << std::endl;
std::cout << "std::string{\"" << *obj << "\"}" << std::endl;
};
};
struct Container {
static Child child;
static void initChild(Child *);
};
Child Container::child{Container::initChild}; // Invocate Child constructor
void Container::initChild(Child* childPtr) {
using T = Container;
childPtr->name = "child in container";
childPtr->size = sizeof(T);
};
Parent* get() {
return &Container::child; // Upcast Child
};
int main() {
Parent* ParentPtr = get();
const std::string value = "show a string";
ParentPtr->show(&value);
return 0;
}
输出是:
name = child in container
size = 1
level = 0
std::string{"show a string"}
特殊规则仅适用于Parent
的构造函数
期间,因为那时还没有
Child
。一旦对象完全构造完毕,虚函数重写将可用。
并且
get()
只是向上转换指针,它没有对对象进行切片,因此指针指向一个完整的 Child
对象。