0

Lately I have been having difficulties with constructors, and the different attempts from other questions and guides always have some form of segfault waiting for me at runtime (making compiling 80% of my time spent programming).

The following example shows the basic idea on what I am trying to accomplish:

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?
}

With this example I have a bunch of simpler structs (similar to Coord3 and Stat). These structs are at the base level of my "engine", and are used accordingly to make higher level structs, then those are used to make the highest level structs (such as Item being item related information and SimpleChar having generic RPG character statistics, like an inventory and stats). The errors I get are so different according to the situation that it was difficult to keep track them all, but the most interesting one was a SEGFAULT on:

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

So basically what I ask is:

  1. When are the default constructors invoked?
  2. When the constructors are used, do they also invoke their member's constructors?
  3. What would be the correct way to declare these members both in the classes and main()?
  4. What is the correct way to create the constructor?

EDIT: The code has been spruced up for anyone that is way too obsessed with if the code is "valid by syntax" instead of actually answering the question.

EDIT 2: Since the SEGFAULTs are not created from constructor format then I ask if it is possible to get a SEGFAULT if an instance variable is too large in size? I mainly ask this because recently I have changed a class member to a pointer instead of an object and it worked fine.

Molma
  • 171
  • 9
  • A note about the semicolons: I know some of them are wrongly placed incase anyone calls that as part of the issue :) – Molma Nov 29 '13 at 05:16
  • Constructors are not related to your SEGFAULT. A SEGFAULT is accessing memory that was not allocated. – woolstar Nov 29 '13 at 05:19
  • @woolstar:If this is the case then what is not being allocated? the `shared_ptr Items` were always able to tell me if they were null or not(they worked in a previous version). Suddenly they dont work? Or is it the `shared_ptr` itself that is not allocated? – Molma Nov 29 '13 at 05:25
  • @timrau, because the constructor is private. – Shoe Nov 29 '13 at 05:44
  • @Jefffrey Get it. Didn't notice that. – timrau Nov 29 '13 at 05:46
  • This is not a situation as to if the code is compilable, this snippet is only an example about the constructors and how I have declared them. – Molma Nov 29 '13 at 05:48

3 Answers3

2

when you declear a class like:

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

But if you write:

class foo{};

The compiler will supply a default constructor for you. When you write:

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


};

Inside main() if you want to initialise an object with default constructor:

className instanceName; 

is enough.

When You write:

SimpleChar myChar;

The following constructor is called:

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

An additional point ; is mandetory after a class or struct definetion, which is absent in struct item{}

And default access specifier of struct is public but in class it is private, Which means you can not create object in main with default constructor.

Edit: "if an instance variable is too large in size" you may get a std::bad_alloc if it is being allocated dynamically in runtime but generally not a segfault. it happens when you access area you do not own.

deeiip
  • 3,319
  • 2
  • 22
  • 33
  • Alright, I understand now. This means that the way I implemented them in the actual code is correct. Also as stated before: I know about the misplaced and missing semicolons, this was a pretty sloppy example. :) – Molma Nov 29 '13 at 05:32
  • ony your mentioned code can not cause a segmentation fault. So I wanted to answer your 5 questions related to constructor. the reason of your segfault is somewhere else, not in your mention ed code. – deeiip Nov 29 '13 at 05:35
  • Would there be a possible chance that the member of the classes member is not accessible? for example: `if(myChar->_items().inventory[a].get()!=NULL)`, `myChar` is a pointer to an object. `items` is a private member of `myChar`, where `ItemData &_items(){return items;};` is the getter function. and `inventory[a]` is a public member of `items`, in the form of a `shared_ptr`. Would this possibly cause a SEGFAULT? – Molma Nov 29 '13 at 06:02
  • "myChar is a pointer to an object items is a private member of myChar"- you'd get a compile time error stating that. – deeiip Nov 29 '13 at 06:09
  • If this is the case then how would I avoid this? 1: Should `myChar` be a regular object? 2: Is the getter function wrong? 3: Is it that since I set `items` to be private that i cannot use it's members anywhere outside `myChar`'s scope? 4: Using getters will not allow me to use an instance variable's members? – Molma Nov 29 '13 at 06:16
  • Also I realized what you meant after posting the previous comment. I should probably make this another question, to keep the situation clear – Molma Nov 29 '13 at 06:19
1

1: When are the default constructors invoked?

Default constructors are called when:

  • You create an object without passing parameters

    MyClass* myClass = new MyClass(); //<- this is you invoking it.

  • When you inherit from a class and dont specify a constructor in the initialization list for that base class.

    class MyClass: public BaseClass { MyClass() { } };

    MyClass* myClass = new MyClass(); // <-- this will invoke the default constructor for "MyClass" and "BaseClass".

  • When you put an object in any stack and dont specify a constructor.

    void methodA() { MyClass myClass; // <-- this will invoke the default constructor for "MyClass" }

    Same happens if you declare an object as a member of a class in its stack.

    class MyClass { MyClass() { }

    DifferentClass m_member;
    

    };

If you dont specify a different constructor for m_member in the initialization list of MyClass, its default constructor will be used.

2: When the constructors are used, do they also invoke their member's constructors?

As long as they are in the stack and not in the heap, and you dont specify otherwise in the initialization list of the class. Yes.

3: What would be the correct way to declare these members both in the classes and main()?

It will depend on what you want, if you want to initialize them with its default constructor, you can just declare them as follow:

MyClass myClass; //<- this is fine.

4: What is the correct way to create the constructor?

A good practice is to ALWAYS initialize your members in the initialization list, for example:

struct Stat
{
    int Str,Dex,Int;

    Stat(): Str(0), Dex(0), Int(0)
    {};
};
AngelCastillo
  • 2,385
  • 2
  • 18
  • 26
0

A simple example of how the default constructor works:

class base 
{
    int i;
public:

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


int main()
{

    base a;// here is the point of doubt
    getch();
}
Matt Bryant
  • 4,841
  • 4
  • 31
  • 46