我有一个C++类,我只希望它在堆栈上实例化.我正在使用api访问以另一种(解释)语言开发的内容,该语言带有自己的垃圾收集.这种语言中的机制足以将它在堆栈中找到引用的任何内容留下来,并且由于这个本机类包含这样的引用,因此对于正确的行为来说,它本身就是C++类的用户是至关重要的.永远不要尝试在其他任何地方分配它的实例.
注意,我不仅要禁止我的类的实例被分配new(如果这是我需要做的全部,我可以重载类的new运算符并将其设为私有,或者从C++ 11开始明确删除它),但也要禁止该类的任何静态或可能的全局实例.安全地实例化这个类的唯一有效方法应该在堆栈上,我想以某种方式保证.据我所知,new私有或删除它也不会阻止另一个类被我的类声明为成员变量和在堆上分配的实例.
我现在如何处理这个问题就是将"Local"作为类名称的一部分,作为对用户的友好提醒,该实例仅用于堆栈,但当然,这不是'实际上是由编译器或任何其他机制强制执行的,我更喜欢一种更具可执行性的解决方案.
理想情况下,我想在编译时确保这一点,如果使用不正确则编译失败.如果这根本不可能,那么在构造实例时在运行时抛出异常仍然是可接受的回退.在C++ 11或C++ 14中工作的解决方案很好.
请注意,这个问题肯定是不一样的这一个,它只是想防止allocaton与new
在以下代码中:
class A {
};
class B : public A {
};
class C : public A {
int x;
};
int main (int argc, char** argv) {
A* b = new B();
A* c = new C();
//in both cases, only ~A() is called, not ~B() or ~C()
delete b; //is this ok?
delete c; //does this line leak memory?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当使用具有成员函数的非虚析构函数(如C类)调用类上的delete时,内存分配器可以告诉对象的正确大小是什么吗?如果没有,记忆是否泄露?
其次,如果类没有成员函数,并且没有明确的析构函数行为(比如B类),那么一切都好吗?
我问这个是因为我想创建一个扩展的类std::string,(我知道不推荐,但为了讨论它只是承担它),并重载+=,+运算符.-Weffc ++给了我一个警告,因为它std::string有一个非虚拟析构函数,但是如果子类没有成员并且不需要在它的析构函数中做任何事情,这是否重要?
FYI +=重载是进行正确的文件路径格式化,因此可以使用路径类,如:
class …Run Code Online (Sandbox Code Playgroud) 我正在使用OpenSplice DDS,在那里,几乎所有C++类(我使用的基本类,如果重要的话我可以提及它们)将new运算符重载为私有(以防止用户使用它们).我不明白,为什么有人这样做?有人可以提供一些显示这种必要性的例子吗?
我为什么需要new:因为大多数这些类都没有默认的构造函数,所以我需要稍后在我的实现中通过a初始化它们unique_ptr.
简单的伎俩:另一方面......我很容易欺骗这个!我可以用另一个类包装这个类,并使用new我想要的所有,对吧?因此,我不明白动机,感觉就像糟糕的风格.有人能解释一下吗
编辑:
只是为了澄清:提供一个无法逃脱的好例子是一个很好的答案.对于所有看到new运营商私有的人都会有所帮助.
假设我在库中定义了一个类
class Base {};
Run Code Online (Sandbox Code Playgroud)
我将该类发布给用户.
一个用户定义了一个新类
class Derived : public Base {}
Run Code Online (Sandbox Code Playgroud)
我可以做些什么Base来防止用户Derived在堆上创建实例?
例如,这是允许的
Derived dd;
Run Code Online (Sandbox Code Playgroud)
这不是
Derived* dd = new Derived();
Run Code Online (Sandbox Code Playgroud)
谢谢,
c++ ×5
c++-faq ×1
c++11 ×1
c++14 ×1
inheritance ×1
new-operator ×1
overloading ×1
polymorphism ×1