views:

238

answers:

6

Is this possible? For example if i write

Car myCar;

Then the constructor taking no arguments of Car is called. It results in an error if there is only a constructor taking arguments.

In Java I can easily declare an object and create it later using the exact same statement as above.

+7  A: 

To do what you did in Java, you declare a pointer in C++:

Car* myCar;
stefaanv
Yes but then I have to create it on the heap..
Nils
No you don't. You could later do Car otherCar; myCar = (also if you want to compare to java, objects live on the heap there too)
nos
@Nils, you have no other choice. Writing in C++ isn't same as in Java. If you want C'tor not to be called you have to instantiate object on heap.
Artem Barger
Ok.. but then it requires an empty constructor to create otherCar.. maybe the easiest thing is to just add one..
Nils
@Nils, no you later mention you wanted it to point to myVector[i].So just do Car *myCar = or use a reference if you can:Car . You do not have to instantiate it on the heap as @Artem Barger says, a pointer to an element on the stack is fine too.
nos
So I can do... Car *myCar; for(int i=0..) if(myVector[i].label == 3) { myCar = myVector[i];} and then I can use myCar just as an ordinary object created on the stack?
Nils
I mean I don't have to delete it, do I?
Nils
@Nils: No you don't have to delete it in this case, but probably not for the reason you think. You have to be careful to separate value and reference/pointer semantics. What you are used to in Java is reference semantics. When using Stack based variables you (usually) have value semantics. In this case here you take a reference to a stack based object (well the vector is stack based, the content may live on the heap, but this doesn't matter in this case) so you need not (even may not) delete it, but you need to be sure that the reference doesn't outlive the vector.
Fabio Fracassi
+5  A: 

No, this is not possible. You could come up with some dirty hacks based on placement new which may get you close, but I doubt you are interested in them.

Why do you want to do that? Perhaps there is some clean way how to achieve that in a C++ style.

If you only want to create a variable which will point to some object later, this is what pointers are used for in C++.

auto_ptr<Car> car;

car = new Car(xxx);

Or "old way":

Car *car = NULL;

car = new Car(xxx);

delete car;

To find an item in a vector a code like this is commonly used:

std::vector <Car> cars;
Car *find = NULL;
for(std::vector<Car>::iterator car = cars.begin(); car != cars.end(); ++car )
for (int i=0; i<cars.size(); i++)
  if (Match(*car,xxx)
  {
    find=car;
    break;
  }

In many situations you would probably also prefer not to have a vector of cars, but of pointers to cars as well.

Suma
Well I have to find an object from a vector of objects and so I don't have to use myVector[i] all the time, I would like to create a reference first and the loop over the list and attach the object to the reference created before the loop.
Nils
So you can use car =
Artem Barger
@Nils You probably want to use a vector iterator instead of indexing into the vector: `for(std::vector<Car>::iterator iter = myVector.begin(); iter != myVector.end(); ++iter)`, which lets you use `*iter` to refer to the current object. Either way, you can make a reference in the loop that corresponds to the current element, either `Car` or `Car`
Michael Mrozek
is there any reason why you wrote ++iter instead of iter++?
Nils
Just a convention to indicate you do not need the result (and to make compiler job easier). You can find multiple topics about the difference, in this particular case it does not really matter.
Suma
@Michael: Agreed, this is a more "canonical" way, so that other containers may be used easily. Updated the code.
Suma
@Nils It avoids needing to create a temporary copy of the iterator
Michael Mrozek
+8  A: 

Well you confusing, in Java everything is a reference( or even you can think of like pointers) to objects and not the objects themself. So you probably what to do like this:

Car* car = NULL;

and then later explicitly call a c'tor by:

car = new Car( params...);

and don't forget to call delete after you finish using car object.

delete car;
Artem Barger
I would suggest Car* car = 0; though, otherwise he'll fall into the trap that C++ doesn't initialize variables with null, other than Java.
Frank
correct. fixed.
Artem Barger
+1  A: 

You could also use pointers, eg

Car *myCar;

Later you'd write:

myCar = new Car();
Mononofu
+3  A: 

What you're used to in java isn't declaring the object and creating it later, but declaring the reference and creating the object to which the reference refers later. In C++, what you're looking for is:

Car *MyCar;
MyCar = new Mycar;
A: 

As discussed, the literal way to represent java-objects in C++ is by using pointers to class objects.

Using C++ pointers with the new statement has the disadvantage, that the slower heap has to be accessed, and that deleting the object has to be done manually.

Depending on the scope, there are more C/C++ like solutions.

At global or namespace-scope, you can use the extern-specifier to declare an object, defined elsewhere:

extern C c;
<more code>
c(1,2,3);

(The extern keyword tends to be used rarely within C++).

As usual, boost offers an elegant and general solution with the library boost::optional.

This can be used everwhere as follows:

optional<int> oa; // declaration
<more code> 
*oa=3; // construction
DirkM