Page 1 of 1

c++ classes help (Solved)

Posted: Sat Dec 22, 2007 9:26 am
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.

Posted: Sat Dec 22, 2007 12:07 pm
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.

Posted: Sat Dec 22, 2007 1:13 pm
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.

Posted: Sat Dec 22, 2007 3:43 pm
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).

Posted: Sat Dec 22, 2007 6:31 pm
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.

Posted: Sat Dec 22, 2007 10:11 pm
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.

Posted: Sat Dec 22, 2007 10:34 pm
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

Posted: Sun Dec 23, 2007 5:22 am
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?

Posted: Sun Dec 23, 2007 10:31 am
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.