C++ 是否允许从std命名空间(即std::wstring)中的类继承?

C++ 是否允许从std命名空间(即std::wstring)中的类继承?,c++,gcc,stl,g++,C++,Gcc,Stl,G++,类std::wstring缺少“普通”c字符串(和文本)的一些操作 我想在我自己的自定义类中添加这些缺少的操作: #include <string> class CustomWString : public std::wstring { public: CustomWString(const char*); const char* c_str(void); }; 编辑:我希望以某种方式“集中化”。这是因为我有一个

类std::wstring缺少“普通”c字符串(和文本)的一些操作

我想在我自己的自定义类中添加这些缺少的操作:

#include <string>

class CustomWString : public std::wstring {

        public:

            CustomWString(const char*);
            const char* c_str(void);
};
编辑:我希望以某种方式“集中化”。这是因为我有一个项目要从M$-Windows移植,其中有上千个失败的操作

好处是:有一个中心位置定义了要使用的字符串类型,例如:

#ifdef WINDOWS_OS
    typedef std::wstring AppStringClass;
#else
    typedef std::string AppStringClass;
#endif

类模板
std::basic_string
(其中
std::wstring
是一个带有特定模板参数的typedef)没有虚拟析构函数,因此,公开继承它是一个坏主意。

它是合法的,但许多人认为它不可取。问题是标准库模板类没有虚拟析构函数。因此,如果您曾经编写过这样的代码:

std::wstring * p = new CustomWString ;
...
delete p;

您有未定义的行为。

您可以这样做。但我看不出有什么意义,因为std::basic_字符串 (及其具体版本std::string和std::wstring) 不定义虚方法,并具有非虚析构函数。
因此,您无法正确地使用子类来代替std::wstring。

我想您知道
basic\u string
没有定义虚拟析构函数。以多态方式使用
wstring
是错误的。否则,您可以像往常一样使用自定义类

因此,以下情况是危险的:

vector<wstring*> mystrings;
mystrings.push_back(new CustomWString);
...
delete mystrings[0]; // No virtual destructor
向量mystrings;
mystrings.push_back(新自定义字符串);
...
删除mystring[0];//没有虚拟析构函数
直接使用自定义类是可以的,例如

vector<CustomWString> mystrings; // OK
mystrings.push_back("...");
vector mystrings;//好啊
mystrings.push_back(“…”);

反对从STL对象继承的传统论点是,它们没有虚拟析构函数。以向量为例。如果我从中继承:

  class CMyVect : public std::vector<int>
  {
      ...
     int* someMemory;
  public:
     CMyVect()
     {
        someMemory = new int();
     }

     ~CMyVect()
     {
        delete someMemory;
     }
  };
类CMyVect:public std::vector { ... int*someMemory; 公众: CMyVect() { someMemory=newint(); } ~CMyVect() { 删除一些记忆; } };
基类中的非虚拟析构函数意味着,如果该类的用户将一个ponter to ints向量指向一个CMyVect,然后删除该指针,则不会调用析构函数,从而导致内存泄漏。也就是说:

 int main()
 {
     std::vector<int>* vecPtr = new CMyVect();
     delete vecPtr; // invokes vector constructor only, not yours
 }
intmain()
{
std::vector*vecPtr=new CMyVect();
delete vecPtr;//仅调用向量构造函数,而不是您的
}

这并不是说你不能从这些对象继承,但是这个问题可以解决。你必须小心使用你继承的对象,或者C++不需要你的析构函数来启动(不保存任何需要释放的资源)。 STL容器不是为继承而设计的,所以这通常不是一个好主意。C++有许多奇怪的角来忽略它。派生类可能会因另一个STL实现而中断,或者仅因生成环境的更新而中断

但是,我认为这是一个警戒信号,而不是完全的警告。这是一个“你真的确定你在做什么,你知道所有的含义,并且对所有的选择都有很好的理由吗?”

在您的情况下:提供额外的构造函数是可以的(因为公共接口是文档化的,您可以复制它),只要您不引入新的数据成员或VMT,切片或非虚拟析构函数就不是问题。(记住,C++标准在删除没有虚拟DTor的基类指针时声明未定义行为)


但是我不确定在不为字符串提供存储的情况下如何实现
char const*c_str()
。一旦你引入新的数据成员,你就进入了一个地雷的领域

这是可能的,也是合法的。但这是个坏主意。这些类不是为继承而设计的,扩展它们最好不要继承。如果在使用这些类时不小心,就会出现未定义的行为。(类没有虚拟析构函数)

此外,添加这些特定函数似乎不是一个好主意,因为它们依赖于区域设置和编码。你给了全班不止一个责任。在
char
wchar\u t
之间转换的功能属于其他地方。

从一个类“继承”另一个类的能力是一种语言特性。它只是一个正式、简单、枯燥的语言特性,与任何特定的应用程序或任何特定的使用模型无关。它是一个低级工具,可以用于不同的目的。为了回答您的问题,从
std::wstring
类继承是完全合法的

然而,下一个问题是“为什么”的问题。为什么要从
std::wstring
继承

如果您是在OOP范式中设计代码,那么从
std::wstring
公开继承可能不是一个好主意,“may”在这里是一个关键词。OOP中的公共继承通常意味着多态类层次结构中的IS-A关系。类
std::wstring
不是设计为多态的,这就是为什么从它公开继承可能被视为一件相当奇怪的事情的原因

如果您是在不同的范例中设计代码,比如模板元编程一(TMP),那么公共继承可能是一件非常有效的事情。你看,在TMP中,公共继承服务于一个完全不同的目的,甚至与多态性和关系无关

换句话说,如果不考虑全局,就无法对你的问题给出具体的答案。在任何情况下,都要小心“机械”答案
 int main()
 {
     std::vector<int>* vecPtr = new CMyVect();
     delete vecPtr; // invokes vector constructor only, not yours
 }