调用默认构造函数的正确方法是什么?

时间:2013-11-29 05:10:57

标签: c++ struct constructor segmentation-fault member

最近我遇到了构造函数的困难,其他问题和指南的不同尝试总是会在运行时等待我的某种形式的段错误(编译80%的时间用于编程)。

以下示例显示了我要完成的基本想法:

struct Coord3{
    float x, y, z;
    Coord3() {x=0;y=0;z=0;};///Is this Correct?
};

struct Stat{
    int Str,Dex,Int;
    Stat(){Str=0;Dex=0;Int=0;};
};

struct Item{
    Stat myStats;
    Item(){...};
};

class SimpleChar{
    public: ///to keep things simple for now
    Coord3 pos;
    Stat myStats;
    int level;
    float health;
    Item inventory[20];

    SimpleChar(){
    level=0;
    health=100;
    }///What happens with 'pos', 'inventory' and 'myStats' in this class's constructor?
};

int main(){
    SimpleChar myChar;
    if(myChar.inventory[0].get()!=NULL){...}///this caused the most recent SEGFAULT as mentioned below. Why wouldn't this work?
}

通过这个例子,我有一堆更简单的结构(类似于Coord3Stat)。这些结构位于我的“引擎”的基础级别,并相应地用于制作更高级别的结构,然后用于创建最高级别的结构(例如Item是项目相关信息和{{1}具有通用RPG角色统计信息,如库存和统计信息)。我得到的错误根据情况是如此不同,以至于很难跟踪它们,但最有趣的是SEGFAULT:

SimpleChar

基本上我要问的是:

  1. 何时调用默认构造函数?
  2. 当使用构造函数时,它们是否也会调用其成员的构造函数?
  3. 在类和if(itemSet.inventory[a].get()!=NULL); ///Note: this is originally a shared_ptr AND was in a struct known as 'ItemSet', which held all item information
  4. 中声明这些成员的正确方法是什么?
  5. 创建构造函数的正确方法是什么?
  6. 编辑:如果代码“通过语法有效”而不是实际回答问题,代码已经被任何过于痴迷的人修改过了。

    编辑2:由于SEGFAULT不是从构造函数格式创建的,所以我问如果实例变量的大小太大,是否可以获得SEGFAULT?我主要问这个是因为最近我将一个类成员更改为指针而不是一个对象,它工作正常。

3 个答案:

答案 0 :(得分:2)

当您取消类似的课程时:

class foo{
    public:
    foo(){} // this is default constructor
};

但如果你写:

class foo{};

编译器将为您提供默认构造函数。当你写:

class SimpleChar{
    Coord3 pos;   // default constructor of Coord3 will be called, 
                  //if you need somrthing else do that in SimpleChar constructor;
    Stat myStats; // same
    int level;
    float health;
    Item inventory[20];    // an array will be created that can hold 20 item,
                           // constructor (default) will be called 20 times


};

如果要使用默认构造函数初始化对象,请在main()内部:

className instanceName; 

就够了。

当你写:

SimpleChar myChar;

调用以下构造函数:

SimpleChar(){
    level=0;
    health=100;
    };

在类;

中没有类或结构定义后,附加点item{}是mandetory struct的默认访问说明符是public,但在类中它是私有的,这意味着你不能使用默认构造函数在main中创建对象。

编辑: “如果实例变量的大小太大”如果在运行时动态分配但是通常不是段错误,则可能会得到std::bad_alloc。当你访问你不拥有的区域时会发生这种情况。

答案 1 :(得分:1)

  

1:何时调用默认构造函数?

在以下情况下调用默认构造函数:

  • 您创建一个不传递参数的对象

    MyClass * myClass = new MyClass(); //< - 这是你调用它。

  • 从类继承时,不要在该基类的初始化列表中指定构造函数。

    class MyClass:public BaseClass {     我的课()     {     } };

    MyClass * myClass = new MyClass(); //< - 这将调用“MyClass”和“BaseClass”的默认构造函数。

  • 将对象放入任何堆栈时,不要指定构造函数。

    void methodA() {   MyClass myClass; //< - 这将调用“MyClass”的默认构造函数 }

    如果将对象声明为其堆栈中类的成员,则会发生相同的情况。

    类MyClass {     我的课()     {     }

    DifferentClass m_member;
    

    };

如果你没有在MyClass的初始化列表中为m_member指定不同的构造函数,那么将使用它的默认构造函数。

  

2:当使用构造函数时,它们是否也会调用其成员   构造

只要它们在堆栈中而不在堆中,并且您不在类的初始化列表中另外指定。是。

  

3:在这两者中声明这些成员的正确方法是什么?   classes和main()?

这取决于你想要什么,如果你想用它的默认构造函数初始化它们,你可以将它们声明如下:

MyClass myClass; //<- this is fine.
  

4:创建构造函数的正确方法是什么?

一个好的做法是始终在初始化列表中初始化您的成员,例如:

struct Stat
{
    int Str,Dex,Int;

    Stat(): Str(0), Dex(0), Int(0)
    {};
};

答案 2 :(得分:0)

默认构造函数如何工作的一个简单示例:

class base 
{
    int i;
public:

    base()
    {
        i = 10;
        cout << "in the constructor" << endl;
    }
};


int main()
{

    base a;// here is the point of doubt
    getch();
}