C++无法访问父媒体资源的子媒体资源
C++ can't access child property from parent
谁能解释为什么Driver
init()
方法无法打印name
子项中覆盖的属性?
#include <iostream>
#include <string>
class Driver {
public:
std::string name = "Unknown";
void init() {
std::cout << name << std::endl;
}
};
// need public here to inherit init()
class SpecificDriver : public Driver {
public:
std::string name = "Specific";
};
int main() {
Driver d;
SpecificDriver sd;
// this gives Unknown Unknown =/
d.init();
sd.init();
}
这给出了:
Unknown
Unknown
并且应该是:
Unknown
Specific
现场演示
你没有做你认为你可能做的事情。您正在驱动程序中声明变量"名称",在特定驱动程序中声明变量"名称"。调用基类驱动程序中定义的init()
时,该驱动程序只能访问其自己的值为"unknown"的name
字段。
相反,您应该使用构造函数初始化"name"变量。
喜欢这个:
class Driver {
public:
std::string name;
Driver():name("Unknown"){} //default
Driver(std::string value):name(value){}
void init() {
std::cout << name << std::endl;
}
};
// need public here to inherit init()
class SpecificDriver : public Driver {
public:
SpecificDriver():Driver("Specific"){}
};
int main() {
Driver d;
SpecificDriver sd;
d.init();
sd.init();
}
编辑:现场演示 http://coliru.stacked-crooked.com/a/c453758867454348
在C++中,虚拟继承是选择加入而不是隐式的。
当你有这个代码时
class Driver {
public:
std::string name = "Unknown";
void init() {
std::cout << name << std::endl;
}
};
符号name
将根据当时范围内的内容进行静态解析。
如果稍后声明全局变量name
则它对此代码的含义没有影响。如果您稍后从此类 Driver
派生,则 init
函数在继承该类时不会具有不同的含义,如您的示例所示。
此"静态"调度是C++中的默认行为,因为它是最简单、最快的。特别是,如果您稍后使用模板和继承来执行操作,则以这种方式工作很重要,否则许多代码将产生大量额外的开销。
Alex Zywicki展示了一种实现自己想要的东西的方法。另一种方法是使用虚拟调度来获取字符串。像这样:
class Driver {
public:
virtual std::string name() const {
return "Unknown";
}
void init() {
std::cout << name() << std::endl;
}
};
class SpecificDriver : public Driver {
virtual std::string name() const override {
return "Specific";
}
};
可以通过 CRTP 访问子类的类成员。
#include <iostream>
template <typename Derived>
class Driver {
public:
void init() {
std::cout << static_cast<Derived*>(this)->name << std::endl;
std::cout << Derived::value << std::endl;
}
};
class SpecificDriver : public Driver<SpecificDriver> {
public:
std::string name = "Specific";
static constexpr char* value = "Another specific string";
};
int main() {
SpecificDriver g;
g.init();
}
如果需要一个公共基类来存储这些内容,或者与正常的多态行为相结合,则可以使模板类Driver
从公共基类继承。
相关文章:
- 具有瞬态资源的RAII类
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 允许从 std::map 的密钥窃取资源?
- 参考资源文件VC++中的$(SolutionDir)
- 如何维护资源管理器项目视图中当前可见的项目列表
- 将 std::allocate_shared 与多态资源分配器一起使用
- 使用RAII在给定次数的迭代后重新分配资源
- 资源管理设计模式
- 如何跨平台将二进制资源构建到程序中?
- SetDlgItemInt 不会更改嵌入资源的编辑框
- Klocwork Inside的资源泄漏
- 从存储为 Windows 资源 (c++) 的 png 中获取 png 文件数据
- C++链接时间资源"allocation"而不定义
- 使用 Bazel 生成 QT 资源文件
- 编译器资源管理器和 GCC 具有不同的输出
- 使用 Bazel 编译 QT 应用程序时访问资源
- 根据需要声明资源,而不重复它们
- C++ VS2015:媒体资源页是共享设置
- 自动驾驶汽车 Android "opencv.dir"未在本地媒体资源中设置 - Android Studio
- C++无法访问父媒体资源的子媒体资源