c++ classes help (Solved)

Discussion about everything. New games, 3d math, development tips...
Post Reply
LosNir
Posts: 43
Joined: Wed Dec 19, 2007 6:38 pm
Location: Israel
Contact:

c++ classes help (Solved)

Post by LosNir »

Hi, I'm new in c++ and i am trying to create an instance of class A in class B, but, but it wont work!

Code: Select all

class A
{
    public: int Foo;
    
    public: void Init()
    {
            Foo = 54;
            cout<<"This is class A! Foo is: "<<Foo;
    }   
};

class B
{
    public: int Bar;
    public: A* obj;
    
    public: void Init()
    {
            Bar = 96;
            cout<<"This is class B! Foo from A is: "<<obj->Foo;
    }   
};

The instance is created, but the Init of B always returns 0
This is class B! Foo from A is: 0
I also tried to replace:

Code: Select all

    public: A* obj;
    
    public: void Init()
    {
            Bar = 96;
            cout<<"This is class B! Foo from A is: "<<obj->Foo;
    }   
With:

Code: Select all

    public: A obj;
    
    public: void Init()
    {
            Bar = 96;
            cout<<"This is class B! Foo from A is: "<<obj.Foo;
    }   
But now it returns:
This is class B! Foo from A is: 2293672
It's getting me nervous! :(

Edie:

Never mind, i realized that creating an instance on the main and calling Init is only valid for that specific instance, and wont be valid at class B.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Simply said, your code sucks completely. You have no initialisers, use pointers which point to nothing, ... This code is simply wrong, never use it, learn C++ instead.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Code: Select all

class A
{
    public: 

    int Foo;

    A() : Foo(54)
    {
            std::cout << "This is class A! Foo is: " << Foo << std::endl;
    }   
};

class B
{
    public: 

    int Bar;
    A* obj;
   
    B() : Bar(96), obj(new A())
    {
            std::cout << "This is class B! Foo from A is: " << obj->Foo << std::endl;
    }   
}; 
That should do the trick.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

A little improvement still: Don't use 'new' in the init list, because an exception would leave an only partially initialised object. It's better to put mathd calls which might throw into the constructor's body (where it might also be caught directly).
LosNir
Posts: 43
Joined: Wed Dec 19, 2007 6:38 pm
Location: Israel
Contact:

Post by LosNir »

hybrid, i don't use that code, it was just a quick code for example on my problem.

And what points to nothing? i know about Bar, i just thought i will use it, but i didn't, and i was to lazy to delete it.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

No, it's not the problem with Bar. It's the A* pointer in B, which is never initialized, but dereferenced. This should immediately kill your application (at best), but might just give any results as in your case.
Then you tried to get some value from A from the member object, but that was created with default constructor, which does not call Init. Instead of using an Init function (which makes sense only if you do other things than initialising members) you should have created a proper constructor and the second case would have been fairly ok, at least for a first encounter with C++. But still much to learn, especially regarding OOP in general.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Don't use 'new' in the init list, because an exception would leave an only partially initialised object
No.

If an exception is thrown from the the init list or constructor and not caught in the function try block or constructor, there would never be a partially constructed object. There is no way for the user to get a reference or pointer to such an object. In the worst case they would see a resource leak. In the case shown, there is only one operation that can throw [the call to new], so there is no potential for loss.

The C++ language requires that the destructor for all constructed members to be invoked if an exception is thrown from the constructor. If you use the RAII pattern, then you would use a resource handle that would correctly release any resource that it 'owned', like an auto_ptr<> or shared_ptr<> would.

If you do put the code into the constructor body [i.e. between the curly braces] but don't use RAII, then you need to write try/catch code in the body to correctly release the initialized parts of the object.

Also, since when has Irrlicht been 'exception safe'? :)

Travis
fireside
Posts: 158
Joined: Thu Dec 01, 2005 10:55 pm

Post by fireside »

Um, I don't understand much of that, but isn't there supposed to be a delete in the destructor if you use a new in the constructor?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

But the thing is that if you have another pointer member following the possible exception initialiser, the destructor will propbably have a delete for that pointer. Coming back from the exception with an only partially initialized object (which I was referring to) the destructor would call delete on the pointer, freeing arbitrary memory.
Even if Irrlicht is not making use of any of such things, it's better to learn this stuff and use it, even if it's not necessary.
Post Reply