C++ 如何在构造函数中销毁对象并返回NULL
我正在尝试编写一个cpp模块,它必须检查初始化是否正确。它需要至少用一个非空指针初始化。否则,它需要删除自身并返回NULL。下面的程序似乎确实销毁了该对象,但它似乎没有返回null 这是怎么回事C++ 如何在构造函数中销毁对象并返回NULL,c++,pointers,C++,Pointers,我正在尝试编写一个cpp模块,它必须检查初始化是否正确。它需要至少用一个非空指针初始化。否则,它需要删除自身并返回NULL。下面的程序似乎确实销毁了该对象,但它似乎没有返回null 这是怎么回事 #include <iostream> using namespace std; class cmod { public: cmod(int *p1=NULL, int *p2=NULL) { if( p1 == NULL
#include <iostream>
using namespace std;
class cmod {
public:
cmod(int *p1=NULL, int *p2=NULL)
{
if( p1 == NULL && p2 == NULL){
delete(this);
}
else
cout << __func__ << ": Initialized" << endl;
if(p1 != NULL)
cout << "*p1 = " << *p1 << endl;
if(p2 !=NULL)
cout << "*p2 = " << *p2 << endl;
}
~cmod()
{
cout << __func__ << ": Destroyed" << endl;
}
};
int main()
{
int a=10, b = 20;
cmod *p = new cmod();
if(p == NULL)
cout << __func__ << ": Unable to initialize" << endl;
cmod *p1 = new cmod(&a, &b);
}
为什么行无法初始化不打印
更新:
在看了所有答案后,我得出以下结论:
#include <iostream>
using namespace std;
class cmod {
private:
int *l1,*l2;
cmod()
{
throw std::runtime_error("Failed to construct object. No arguements");
}
cmod(int *p1=NULL, int *p2=NULL)
{
if( p1 == NULL && p2 == NULL){
throw std::runtime_error("Failed to construct object. Both args NULL");
}
else
cout << __func__ << ": Initialized" << endl;
if(p1 != NULL)
l1 = p1;
if(p2 !=NULL)
l2 = p2;
}
~cmod()
{
cout << __func__ << ": Destroyed" << endl;
}
public:
static cmod * initialize(int *p1=NULL, int *p2 = NULL)
{
if( p1 == NULL && p2 == NULL){
return NULL;
}
else
return new cmod(p1,p2);
}
void dump()
{
cout << __func__ << ": a = " << *l1 << endl;
cout << __func__ << ": b = " << *l2 << endl;
}
int main()
{
int a=10, b = 20;
cmod *p = cmod::initialize(NULL, NULL);
if(p == NULL)
cout << __func__ << ": Unable to initialize" << endl;
cmod *p1 = cmod::initialize(&a, &b);
if(p!=NULL)
p->dump();
if(p1!=NULL)
p1->dump();
}
#包括
使用名称空间std;
类cmod{
私人:
int*l1,*l2;
cmod()
{
抛出std::runtime_错误(“构造对象失败,无参数”);
}
cmod(int*p1=NULL,int*p2=NULL)
{
如果(p1==NULL&&p2==NULL){
抛出std::runtime_错误(“未能构造对象。两个参数均为NULL”);
}
其他的
cout构造函数将始终返回其类的对象,除非它引发异常。因此,您要做的是:
cmod(int *p1=NULL, int *p2=NULL)
{
if( p1 == NULL && p2 == NULL)
throw std::runtime_error("Failed to construct object.");
}
您需要使用factory模式创建对象,以便将对象创建委托给factory。这样factory可以控制是否应创建对象
因此,创建另一个名为cmodFactory的类,它有一个返回cmod的静态方法。在这个静态方法中,您可以检查是否要创建对象并相应地返回
添加示例代码:
#include <iostream>
using namespace std;
class cmod {
public:
cmod(int *p1=NULL, int *p2=NULL)
{
cout << __func__ << ": Initialized" << endl;
if(p1 != NULL)
cout << "*p1 = " << *p1 << endl;
if(p2 !=NULL)
cout << "*p2 = " << *p2 << endl;
}
~cmod()
{
cout << __func__ << ": Destroyed" << endl;
}
};
class cmodFactory {
public:
static cmod * getCmodInstance(int *p1=NULL, int *p2=NULL)
{
if( p1 == NULL && p2 == NULL){
return NULL;
}
else
{
cmod * instance = new cmod(p1, p2);
return instance;
}
}
};
int main()
{
int a=10, b = 20;
cmod *p = cmodFactory::getCmodInstance();
if(p == NULL)
cout << __func__ << ": Unable to initialize" << endl;
p = cmodFactory::getCmodInstance(&a, &b);
if(p == NULL)
cout << __func__ << ": Unable to initialize" << endl;
else
cout << __func__ << ": initialized" << endl;
}
你不能<代码>删除这个< /代码>。考虑在下面的场景中会发生什么:
cmod A; // default constructor: called with both arguments NULL
当A
未在堆上分配,而是存在于堆栈上时。但是使用new
未分配的指针调用delete
是错误的程序(如果幸运的话,它将在运行时崩溃)
正如Harald所指出的,处理构造函数的错误输入的适当且正确的方法是抛出和异常。使用工厂并不完全合适,因为用户可能仍然试图通过其他方式构造对象(除非工厂成为朋友
和建造商私人
或受保护
而禁止这样做).如果您想在构造对象之前验证输入,最好使用执行该操作的静态
成员函数,而不是在构造函数中验证输入。此外,将构造函数设置为私有
,以防止意外误用
class cmod {
public:
static cmod* buildInstance(int *p1=NULL, int *p2=NULL)
{
if( p1 == NULL && p2 == NULL){
return NULL;
}
else {
return new cmd(p1, p2);
}
}
~cmod()
{
cout << __func__ << ": Destroyed" << endl;
}
private:
cmod(int *p1, int *p2)
{
cout << __func__ << ": Initialized" << endl;
if(p1 != NULL)
cout << "*p1 = " << *p1 << endl;
if(p2 !=NULL)
cout << "*p2 = " << *p2 << endl;
}
};
类cmod{
公众:
静态cmod*buildInstance(int*p1=NULL,int*p2=NULL)
{
如果(p1==NULL&&p2==NULL){
返回NULL;
}
否则{
返回新cmd(p1,p2);
}
}
~cmod()
{
cout构造函数不能返回null。构造函数不返回指针。在构造函数中调用delete(this)
是错误的
有一种方法可以取消对象的构造:抛出异常。在这种情况下,新表达式不会返回null。事实上,它根本不会返回。相反,您必须捕获异常才能处理这种情况
为什么“无法初始化”不打印
因为新表达式永远不会返回null,除非使用非抛出变量,并且分配(与对象初始化分离)失败。在这种情况下,分配没有失败,抛出变量(默认值)已使用。delete
不会将指针设置为nullptr
。我想不出另一种说法:不要这样做。您可能需要覆盖类cmod的新的运算符(尽管可能有更好的方法来实现整个过程,即专门用于此目的的设计模式)。如果您想发出对象构造失败的信号,请使用异常。由于不允许使用两个空指针调用构造函数,因此不应使用第一个指针的默认参数,因此请将其删除。当然,要在cmod*p=new cmod();
@barakmanos处捕获它,请(除非你希望这是一个致命的错误,但是你可以调用std::terminate())这不会是一个致命的错误,因为我将初始化很多这样的对象。还有什么方法可以确保只发生这种形式的初始化吗?很抱歉问这些愚蠢的问题。c guy进入cpp。请耐心等待。@preetam:创建构造函数private并提供一个静态的“工厂”函数(make_foo(…)
),该函数在尝试创建对象之前进行检查。这是一个很好的答案。也许一个编码示例会使它更好。此代码仍然调用delete(This)
并允许工厂以外的构造。需要找到一种方法来保护第一类的构造函数,考虑如何保护它不被walter指出的没有任何参数的调用?@preetam,构造函数是私有的buildInstance()
在调用构造函数之前验证输入。
cmod A; // default constructor: called with both arguments NULL
class cmod {
public:
static cmod* buildInstance(int *p1=NULL, int *p2=NULL)
{
if( p1 == NULL && p2 == NULL){
return NULL;
}
else {
return new cmd(p1, p2);
}
}
~cmod()
{
cout << __func__ << ": Destroyed" << endl;
}
private:
cmod(int *p1, int *p2)
{
cout << __func__ << ": Initialized" << endl;
if(p1 != NULL)
cout << "*p1 = " << *p1 << endl;
if(p2 !=NULL)
cout << "*p2 = " << *p2 << endl;
}
};
int main()
{
int a=10, b = 20;
cmod *p = mod::buildInstance();
if(p == NULL)
cout << __func__ << ": Unable to initialize" << endl;
cmod *p1 = cmod::buildInstance(&a, &b);
}