Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在构造函数中销毁对象并返回NULL_C++_Pointers - Fatal编程技术网

C++ 如何在构造函数中销毁对象并返回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

我正在尝试编写一个cpp模块,它必须检查初始化是否正确。它需要至少用一个非空指针初始化。否则,它需要删除自身并返回NULL。下面的程序似乎确实销毁了该对象,但它似乎没有返回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);
}