C++ 如何防止其他人在堆栈上创建类的新实例?
假设您编写了一个类a,构造函数是私有的(以防止其他人在堆栈上创建它),然后有一天另一个开发人员添加了一个新的构造函数,比如a(int),并希望在main()内使用: A(1) 在堆栈上创建它。你如何防止这种情况 我的解决方案: 声明公共构造函数C++ 如何防止其他人在堆栈上创建类的新实例?,c++,class,object,constructor,private,C++,Class,Object,Constructor,Private,假设您编写了一个类a,构造函数是私有的(以防止其他人在堆栈上创建它),然后有一天另一个开发人员添加了一个新的构造函数,比如a(int),并希望在main()内使用: A(1) 在堆栈上创建它。你如何防止这种情况 我的解决方案: 声明公共构造函数 A(void& input ) { Cerr << “please do not create it on stack” << endl ; exit(1); } A(作废和输入) { Cerr很
A(void& input )
{
Cerr << “please do not create it on stack” << endl ;
exit(1);
}
A(作废和输入)
{
Cerr很明显,你无法阻止它。如果其他人可以直接编辑你的代码,那么他们可以做任何他们想做的事。在评论中这样说:
class A
{
private:
// This is private on purpose to prevent allocation on the stack.
// We'll fire you if you ever write a new constructor that isn't private.
A();
};
class DoNotStackConstruct {
protected:
DoNotStackConstruct(const char* dummy) {}
};
class A : protected DoNotStackConstruct {
private:
A () : DoNotStackConstruct ("PLEASE make all A constructors private!") {
// your code here
}
public:
static std::tr1::shared_ptr<A> newA() {
return std::tr1::shared_ptr<A>(new A);
}
/* ... a bunch of code ... */
/* ... then someone later adds the following ... */
public:
A (int i) {
// can't force them to make it private, but...
// this won't compile without mentioning DoNotStackConstruct
}
};
这个评论是开玩笑的(大部分)但它指出了一个重要的概念。禁止堆栈分配之类的代码约定需要通过同行评审来实施。正如其他人所说,理论上其他人可以随意更改代码。但良好的同行评审过程将有助于控制这种情况。嗯,这比一些聪明的编译器技巧更具成本效益新员工可能不一定理解。我认为您需要的解决方案是以下步骤
为构造函数提供“私有”访问权限
创建一个非成员静态函数,该函数通过new或malloc创建实例并返回它
使用函数创建类的实例
我相信这些步骤可能会解决您的问题。正如其他人所说,您不能阻止能够编辑您的类的人让它做几乎任何事情……但是
…如果你想要一个比注释更易于编译器执行的方法,你可以从一个没有默认构造函数的类继承。任何编写构造函数的人都会(希望)注意到它。你可以让它的名字提醒人们采取某些预防措施
大概是这样的:
class A
{
private:
// This is private on purpose to prevent allocation on the stack.
// We'll fire you if you ever write a new constructor that isn't private.
A();
};
class DoNotStackConstruct {
protected:
DoNotStackConstruct(const char* dummy) {}
};
class A : protected DoNotStackConstruct {
private:
A () : DoNotStackConstruct ("PLEASE make all A constructors private!") {
// your code here
}
public:
static std::tr1::shared_ptr<A> newA() {
return std::tr1::shared_ptr<A>(new A);
}
/* ... a bunch of code ... */
/* ... then someone later adds the following ... */
public:
A (int i) {
// can't force them to make it private, but...
// this won't compile without mentioning DoNotStackConstruct
}
};
类DoNotStackConstruct{
受保护的:
DoNotStackConstruct(const char*dummy){}
};
A类:受保护的DoNotStackConstruction{
私人:
A():DoNotStackConstruct(“请将所有构造函数设置为私有!”){
//你的代码在这里
}
公众:
静态std::tr1::共享\u ptr
然后,他们将能够委托给A()
,而无需访问源代码行并复制“嘿,不要将构造函数公开!”但默认情况下,它们在第一次尝试时仍然会得到编译器错误。我可以问一下为什么要阻止这个问题吗?给我们一个令人信服的理由,我们可以给你一个更好的实现。基于此,C++的一个要点就是给人们尽可能多的工具来执行一个代码条的规则。编译时使用se。没有一个是完美的……你可以说不应该为const
费心,因为可以编辑你的代码的人可以const\u扔掉它,但是const的正确性还是会犯很多错误。没有什么“愚蠢的”关于想利用书中的每一个技巧来帮助你的代码库的实践和协议,并减少错误。甚至可以为这种情况做……看我的答案。@ HooTiLoFoo:除了C++,每当你可以构造一个对象,你可以随时构建它。e> A;
和std::unique\u ptr A;
?我完全支持编译器强制执行,您提出的解决方案很有趣,也不太麻烦,但在这种情况下,它根本不起作用。@MatthieuM。好了,我们又开始画画了:-/是的,如果您只是从工厂方法返回一个指针,没有多大区别,但是如果你返回一个共享的\u ptr(例如)这种事情可能会影响到不同的地方。deleteA
方法完全没有必要,构造函数是private
,而不是析构函数。@MatthieuM。最初我让它返回一个共享的\u ptr(这是我使用私有构造函数的唯一原因)但我只是将它配对以进一步“简化”。不过你是对的,所以我将砍掉它…很难决定“油漆”的数量在填写示例时使用,并且很难决定何时实际编译它:-/在一般意义上你肯定是对的…但是这个FGITW答案有多大帮助,真的吗?请参阅我对这个问题的评论和我的答案。事实上,特别是当任何可以添加公共构造函数的人都可以修改类的任何部分时,包括uding实现任何机制来防止堆栈上的分配。