是否存在 C++ 标准库的所有成员都派生自的基 class?
Is there a base class from which all members of the C++ standard library derive?
C++/CLI 有一个 System::Object class 来满足这个目的,但我似乎无法在标准库中找到一个。基本上我正在写一组 classes,我希望基数 class 将 std::string
的向量存储在 content
属性 中,但是派生的 classes 可能需要存储其他东西的向量(甚至可能是我自己的 classes)。这似乎是一个奇怪的目标,但我正在编写一些文件访问 classes 来让我更轻松地操作不同格式的文件。 base File
class 会将每一行存储在一个字符串中,作为向量的一部分 - 但是 class for JSON,例如,可能需要存储 JS-Style collections/objects,等等
我能想到的唯一方法是让 content
属性 对象向量(或其他一些通用基础 class - 我可以派生任何自定义 class也是出于多态性的缘故从它中提取)然后根据正在使用的子对象的类型将其转换回任何必要的类型。我很快发现我在任何地方都找不到 std::object
(或类似的)的任何提及。
这个例子应该展示我正在尝试做的事情:
class File {
protected:
std::vector<std::object> _content;
public:
//Contructors/methods/etc.
std::string getItemAt(size_t index) {
return static_cast<std::string>(this->_content[index]);
}
void setItemAt(size_t index, std::string value) {
this->_content[index] = static_cast<std::object>(value);
}
};
class JSONFile: File {
public:
//Constructors/methods/etc.
SomeObject getItemAt(size_t index) {
return static_cast<SomeObject>(this->_content[index]);
}
void setItemAt(size_t index, SomeObject value) {
this->_content[index] = static_cast<std::object>(value);
}
};
请注意,此示例假定 std::object
存在,并且 SomeObject
将是用于处理 JSON(同样,例如 - 这可以是任何内容)数据的任何内容. SomeObject
显然会派生自 std::object
.
任何建议将不胜感激,或如果我对此完全错误,请提供有关我如何做到这一点的任何反馈,以便 std::object
不需要的东西将不胜感激:)
Is there a base class from which all members of the C++ standard library derive?
简短的回答是"No."
长答案是 "Definitely not."
可以在相关的 SO 站点上看到提供更多详细信息的答案:Why is base-for-all-objects discouraged in C++。
没有
因为 C++ 就是 "you only pay for what you use"。
std::object
的界面会是什么样子?如果有任何成员函数,这些成员函数必须是 virtual
才有用,由于动态调度会导致运行时成本。
如果假设的 std::object
是一个空的 class,您可以用 std::object
引用做什么?不多,因为它没有任何成员函数可以调用。当它们没有任何共同点时,为什么要让所有东西都来自一个单一的基础。
如果您 真的 需要为所有 classes 提供一个基础,您可以随时编写一个。但注意这样做 might not be a good design decision.
当我看到你定义
std::vector<std::object> _content;
它告诉我,您的目标是使用模板进行泛型编程,而不是使用继承进行面向 object 的编程。这个是std::vector和co.的同款,应该不会太陌生吧
您的代码可以是:
template <typename FileObject>
class File {
public:
std::vector<FileObject> _content;
public:
//Constructors/methods/etc.
FileObject getItemAt(size_t index) {
return this->_content[index];
}
void setItemAt(size_t index, std::string value) {
this->_content[index] = FileObject(value);
}
};
然后用作
json_files = File<JSONObject>();
json_files.setItemAt(1, "{}");
或者如果您有特殊操作要在 json object 列表上执行,该函数可以采用显式 File<JSONObject>
参数。也可以从 File<JSONObject>
继承,但不鼓励混合和匹配 OO/Generic。
现在,更接近您的标题问题:您不能轻易地将不同的文件类型存储在同一个向量中,但请考虑如何实现它。 File<int>
的存储要求是什么?对于 File<double>
?这是一个核心点,您的 OO/inheritance 解决方案将变得笨拙,并且使用泛型编程使得无法 尝试 ,这很好。
C++/CLI 有一个 System::Object class 来满足这个目的,但我似乎无法在标准库中找到一个。基本上我正在写一组 classes,我希望基数 class 将 std::string
的向量存储在 content
属性 中,但是派生的 classes 可能需要存储其他东西的向量(甚至可能是我自己的 classes)。这似乎是一个奇怪的目标,但我正在编写一些文件访问 classes 来让我更轻松地操作不同格式的文件。 base File
class 会将每一行存储在一个字符串中,作为向量的一部分 - 但是 class for JSON,例如,可能需要存储 JS-Style collections/objects,等等
我能想到的唯一方法是让 content
属性 对象向量(或其他一些通用基础 class - 我可以派生任何自定义 class也是出于多态性的缘故从它中提取)然后根据正在使用的子对象的类型将其转换回任何必要的类型。我很快发现我在任何地方都找不到 std::object
(或类似的)的任何提及。
这个例子应该展示我正在尝试做的事情:
class File {
protected:
std::vector<std::object> _content;
public:
//Contructors/methods/etc.
std::string getItemAt(size_t index) {
return static_cast<std::string>(this->_content[index]);
}
void setItemAt(size_t index, std::string value) {
this->_content[index] = static_cast<std::object>(value);
}
};
class JSONFile: File {
public:
//Constructors/methods/etc.
SomeObject getItemAt(size_t index) {
return static_cast<SomeObject>(this->_content[index]);
}
void setItemAt(size_t index, SomeObject value) {
this->_content[index] = static_cast<std::object>(value);
}
};
请注意,此示例假定 std::object
存在,并且 SomeObject
将是用于处理 JSON(同样,例如 - 这可以是任何内容)数据的任何内容. SomeObject
显然会派生自 std::object
.
任何建议将不胜感激,或如果我对此完全错误,请提供有关我如何做到这一点的任何反馈,以便 std::object
不需要的东西将不胜感激:)
Is there a base class from which all members of the C++ standard library derive?
简短的回答是"No."
长答案是 "Definitely not."
可以在相关的 SO 站点上看到提供更多详细信息的答案:Why is base-for-all-objects discouraged in C++。
没有
因为 C++ 就是 "you only pay for what you use"。
std::object
的界面会是什么样子?如果有任何成员函数,这些成员函数必须是 virtual
才有用,由于动态调度会导致运行时成本。
如果假设的 std::object
是一个空的 class,您可以用 std::object
引用做什么?不多,因为它没有任何成员函数可以调用。当它们没有任何共同点时,为什么要让所有东西都来自一个单一的基础。
如果您 真的 需要为所有 classes 提供一个基础,您可以随时编写一个。但注意这样做 might not be a good design decision.
当我看到你定义
std::vector<std::object> _content;
它告诉我,您的目标是使用模板进行泛型编程,而不是使用继承进行面向 object 的编程。这个是std::vector和co.的同款,应该不会太陌生吧
您的代码可以是:
template <typename FileObject>
class File {
public:
std::vector<FileObject> _content;
public:
//Constructors/methods/etc.
FileObject getItemAt(size_t index) {
return this->_content[index];
}
void setItemAt(size_t index, std::string value) {
this->_content[index] = FileObject(value);
}
};
然后用作
json_files = File<JSONObject>();
json_files.setItemAt(1, "{}");
或者如果您有特殊操作要在 json object 列表上执行,该函数可以采用显式 File<JSONObject>
参数。也可以从 File<JSONObject>
继承,但不鼓励混合和匹配 OO/Generic。
现在,更接近您的标题问题:您不能轻易地将不同的文件类型存储在同一个向量中,但请考虑如何实现它。 File<int>
的存储要求是什么?对于 File<double>
?这是一个核心点,您的 OO/inheritance 解决方案将变得笨拙,并且使用泛型编程使得无法 尝试 ,这很好。