开发者

C++ object instantiation and scope

开发者 https://www.devze.com 2023-04-07 04:13 出处:网络
I\'m coming (very recently) from C#, where I am used to instantiating objects like this: Phone myPhone = new Phone();

I'm coming (very recently) from C#, where I am used to instantiating objects like this:

Phone myPhone = new Phone();

simply writing

Phone myPhone;

essentially creates a holder for a class, but it is yet to be initialised so to speak.

now I'm writing a small class in C++ and I have a problem. Here is the pseudo code:

Phone myPhone;

void Initialise()
{
    myPhone = new Phone();
}

void DoStuff()
{
    myPhone.RingaDingDong();
{

In fact this is a little misleading as the above code is what I would LIKE to have, because I want to be able to put all my initialisation code for lots of things into one neat place. My problem is that the line inside initialise is unnecessary in C++, because before that, a new instance is already created and initialised by the very first line. On the other hand if I put the just the first line inside Initialise() I can no longer access it in DoStuff. It is out of scope, (not to mention the differences between using 'new' or not in C++). How can you create simply a holder for a class variable so I ca开发者_JAVA技巧n initialise it in one place, and access it in another? Or am I getting something fundamentally wrong?

Thanks in advance!


If your Phone constructor takes no parameters then your life is pretty simple - you don't need to new up the phone in the Initialize method. It will be created for you when the object is created and the lifetime will be managed for you.

If you need to get parameters to it, and it doesn't have an Initialize() method or some set methods, then you may need to use a pointer (which can sometimes be null) and have Initialize() call new and pass in those parameters. Your other code needs to check if the pointer is null before using it. Also you need to manage lifetime (by writing the big 3) or use a smart pointer such as shared_ptr from C++11. This should not be your first choice.


You can use the new operator on a pointer:

Phone *myPhone;

void Initialise()
{
    myPhone = new Phone();
}

void DoStuff()
{
    myPhone->RingaDingDong();
}

The only two changes are the added * in the declaration of myPhone and the -> instead of . when accessing RinaDingDong(). You will also have to free it since new is allocating memory:

void destroy()
{
    delete myPhone;
}

Note that if you do this myPhone will be a pointer to a Phone not an actual Phone.


I think you need to brush a bit on pointers. What you are trying to do is possible with pointers.

My problem is that the line inside initialise is unnecessary in C++, because before that, a new instance is already created and initialised by the very first line.

This is incorrect. The comment provided by you only holds good for constructors. From your puesdo code, the function initialize is a global function and is not a member function of a class.

On the other hand if I put the just the first line inside Initialise() I can no longer access it in DoStuff. It is out of scope, (not to mention the differences between using 'new' or not in C++).

Please refer any book on pointers, you can have a global pointer and initialize with new. This can be used in doStuff


If your coming from C#, you know that you have two types of object: class and struct.

The class are copied, assigned and passed to function by reference. So, they are using a reference semantic. The class are also allocated in the heap (using new).

The struct are implementing a value copy semantic. Struct are allocated on the stack (int, double and other built-in type are struct). You cannot treat struct polymorphicaly.

In C++ you haven't got this difference. Class and struct are essentially the same (a part the default access level). It is not the declaration of the class to determinate the copy semantic but it is the declaration of the instance to a class.

If you create a pointer the behaviour is very similar to a class in c#. If you create an object the semantic will be similar to a struct in c#.

C++ has also reference, you should read about the difference between pointers and references.


Kate Gregory's answer is the right one, but I wanted to elaborate a little bit. One of the more powerful ideas in C++ is that stack-allocated objects are owned by their containing scope. For example, if you want to write a class which contains a phone, you'd just write this:

class Secretary { 
    Phone myPhone;
};

And now every time a Secretary is created, a Phone object is automatically initialized with its default constructor. More importantly, whenever a Secretary object is destroyed, its contained Phone object is also destroyed. If you want to use a different constructor for the Phone, you can use initializer lists in Secretary's constructor:

class Secretary {
private: // members
    Phone myPhone;
    Phone myCellPhone;

public: // methods
    Secretary() : myPhone("phone constructor", 12, " args") {}
};

In this case myPhone is initialized using its 3-argument constructor, and myCellPhone is initialized using its default constructor as usual.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号