Declaring an object before initializing it in c++ - c++

Is it possible to declare a variable in c++ without instantiating it? I want to do something like this:
Animal a;
if( happyDay() )
a( "puppies" ); //constructor call
else
a( "toads" );
Basially, I just want to declare a outside of the conditional so it gets the right scope.
Is there any way to do this without using pointers and allocating a on the heap? Maybe something clever with references?

You can't use references here, since as soon as you'd get out of the scope, the reference would point to a object that would be deleted.
Really, you have two choices here:
1- Go with pointers:
Animal* a;
if( happyDay() )
a = new Animal( "puppies" ); //constructor call
else
a = new Animal( "toads" );
// ...
delete a;
or with a smart pointer
#include <memory>
std::unique_ptr<Animal> a;
if( happyDay() )
a = std::make_unique<Animal>( "puppies" );
else
a = std::make_unique<Animal>( "toads" );
2- Add an Init method to Animal:
class Animal
{
public:
Animal(){}
void Init( const std::string& type )
{
m_type = type;
}
private:
std:string m_type;
};
Animal a;
if( happyDay() )
a.Init( "puppies" );
else
a.Init( "toads" );
I'd personally go with option 2.

You can't declare a variable without calling a constructor. However, in your example you could do the following:
Animal a(happyDay() ? "puppies" : "toads");

You can't do this directly in C++ since the object is constructed when you define it with the default constructor.
You could, however, run a parameterized constructor to begin with:
Animal a(getAppropriateString());
Or you could actually use something like the ?: operator to determine the correct string.
(Update: #Greg gave the syntax for this. See that answer)

I prefer Greg's answer, but you could also do this:
char *AnimalType;
if( happyDay() )
AnimalType = "puppies";
else
AnimalType = "toads";
Animal a(AnimalType);
I suggest this because I've worked places where the conditional operator was forbidden. (Sigh!) Also, this can be expanded beyond two alternatives very easily.

If you want to avoid garbage collection - you could use a smart pointer.
auto_ptr<Animal> p_a;
if ( happyDay() )
p_a.reset(new Animal( "puppies" ) );
else
p_a.reset(new Animal( "toads" ) );
// do stuff with p_a-> whatever. When p_a goes out of scope, it's deleted.
If you still want to use the . syntax instead of ->, you can do this after the code above:
Animal& a = *p_a;
// do stuff with a. whatever

In addition to Greg Hewgill's answer, there are a few other options:
Lift out the main body of the code into a function:
void body(Animal & a) {
...
}
if( happyDay() ) {
Animal a("puppies");
body( a );
} else {
Animal a("toad");
body( a );
}
(Ab)Use placement new:
struct AnimalDtor {
void *m_a;
AnimalDtor(void *a) : m_a(a) {}
~AnimalDtor() { static_cast<Animal*>(m_a)->~Animal(); }
};
char animal_buf[sizeof(Animal)]; // still stack allocated
if( happyDay() )
new (animal_buf) Animal("puppies");
else
new (animal_buf) Animal("toad");
AnimalDtor dtor(animal_buf); // make sure the dtor still gets called
Animal & a(*static_cast<Animal*>(static_cast<void*>(animal_buf));
... // carry on

Since c++17, there is now an overhead-free way to do this: std::optional. The code in this case would be:
#include <optional>
std::optional<Animal> a;
if (happyDay()) {
a.emplace("puppies");
} else {
a.emplace("toads");
}

The best work around is to use pointer.
Animal a*;
if( happyDay() )
a = new Animal( "puppies" ); //constructor call
else
a = new Animal( "toads" );

You can also use std::move:
class Ball {
private:
// This is initialized, but not as needed
sf::Sprite ball;
public:
Ball() {
texture.loadFromFile("ball.png");
// This is a local object, not the same as the class member.
sf::Sprite ball2(texture);
// move it
this->ball=std::move(ball2);
}
...

There is a way to do this without pointers/heap memory, this syntax is just a bit gibberish. Here is an example using std::string. I don't recommend doing this unless you really need the performance.
uint8_t object[sizeof(std::string)];
int main() {
if(true)
new(&object) std::string("Your arguments");
else
new(&object) std::string("Your other arguments");
(*(std::string*)(&object)).append("");
std::cout << (*(std::string*)(&object));
return 0;
}
The annoying part about this is you have to cast object to a string every time you want to use it:
(*(std::string*)(&object))

Yes, you can do do the following:
Animal a;
if( happyDay() )
a = Animal( "puppies" );
else
a = Animal( "toads" );
That will call the constructors properly.
EDIT: Forgot one thing...
When declaring a, you'll have to call a constructor still, whether it be a constructor that does nothing, or still initializes the values to whatever. This method therefore creates two objects, one at initialization and the one inside the if statement.
A better way would be to create an init() function of the class, such as:
Animal a;
if( happyDay() )
a.init( "puppies" );
else
a.init( "toads" );
This way would be more efficient.

Related

Understanding std::move and its purpose by example [duplicate]

This question already has answers here:
What is move semantics?
(11 answers)
Closed 2 years ago.
Consider the following code:
class c
{
large_type_t i;
public:
// the most simple variant
c( large_type_t i ): i( i ) { }
// move the parameter copied
c( large_type_t i ): i( std::move( i ) ) { }
// copy is done directly in interaction with our class member from original
c( const large_type_t &i ): i( i ) { }
// parameter was constructed in the call, just treat as rvalue
c( large_type_t &&i ): i( std::move( i ) ) { }
// this is here just to show all possible combinations in case someone in the future sees this question and someone answering it wants to explain everything
c( large_type_t &&i ): i( i ) { }
};
What is the best way to do this? Are these all going to boil down to the same code anyway and it doesn't matter? I feel that I am fundamentally not understanding the purpose of move.
Move constructors (or move assignments) provide the means for your program to avoid spending excessive time copying the contents of one object to another, if the copied-from object will no longer be used afterwards. For example, when an object is to be the returned value of a method or function.
This is more obvious when you have an object with, say, dynamically allocated content.
Example:
class MyClass {
private:
size_t _itemCount ;
double * _bigBufferOfDoubles ;
public:
// ... Initial contructor, creating a big list of doubles
explicit MyClass( size_t itemCount ) {
_itemCount = itemCount ;
_bigBufferOfDoubles = new double[ itemCount ];
}
// ... Copy constructor, to be used when the 'other' object must persist
// beyond this call
MyClass( const MyClass & other ) {
//. ... This is a complete copy, and it takes a lot of time
_itemCount = other._itemCount ;
_bigBufferOfDoubles = new double[ _itemCount ];
for ( int i = 0; i < itemCount; ++i ) {
_bigBufferOfDoubles[ i ] = other. _bigBufferOfDoubles[ i ] ;
}
}
// ... Move constructor, when the 'other' can be discarded (i.e. when it's
// a temp instance, like a return value in some other method call)
MyClass( MyClass && other ) {
// ... Blazingly fast, as we're just copying over the pointer
_itemCount = other._itemCount ;
_bigBufferOfDoubles = other._bigBufferOfDoubles ;
// ... Good practice to clear the 'other' as it won't be needed
// anymore
other._itemCount = 0 ;
other._bigBufferOfDoubles = null ;
}
~MyClass() {
delete [] _bigBufferOfDoubles ;
}
};
// ... Move semantics are useful to return an object 'by value'
// Since the returned object is temporary in the function,
// the compiler will invoke the move constructor of MyClass
MyClass someFunctionThatReturnsByValue() {
MyClass myClass( 1000000 ) ; // a really big buffer...
return myClass ; // this will call the move contructor, NOT the copy constructor
}
// ... So far everything is explicitly handled without an explicit
// call to std::move
void someOtherFunction() {
// ... You can explicitly force the use of move semantics
MyClass myTempClass( 1000000 ) ;
// ... Say I want to make a copy, but I don't want to invoke the
// copy contructor:
MyClass myOtherClass( 1 ) ;
myOtherClass = std::move( myTempClass ) ;
// ... At this point, I should abstain from using myTempClass
// as its contents have been 'transferred' over to myOtherClass.
}
What is the best way to do this?
The simplest variant. The reason: Because it is the simplest variant.
Trivial types do not have copy constructors nor move constructors, and "moving" them is same as copying.
Are these all going to boil down to the same code anyway and it doesn't matter?
If optimisation and in particular inline expansion is involved, then probably yes. You can verify whether that is the case for your program by comparing the resulting assembly. Assuming no (or poor) optimisation, the simplest variant is potentially fastest.
Regarding your edit: For non-trivial types, the second variant is best because it moves from rvalue arguments instead of copying.
All of those are different and it very much depends on what large_type_t i; is.
Does it manage dynamically allocated data? If yes and it supports both moving and copy construction then following two constuctors should be used:
c( const large_type_t &i ): mi( i ) { };
c( large_type_t &&i ): mi( std::move( i ) ) {};
Although, it is potentially a mildly less efficient way, but you can use a single constructor for both purposes:
c( large_type_t i): mi( std::move( i ) ) { };
For the above, without std::move it will likely result in unnecessary copying and memory allocations.
If it doesn't manage any dynamically allocated data - then usually moving/copying is the same thing (for exotic types figure it yourself since it's too dependent on circumstances). Thus you only need copy constructor:
c( const large_type_t &i ): mi( i ) { };
For small trivial types, you'd better use the most basic form:
c( small_type_t i ): mi( i ) { };

How to get reference to EXPECT_CALL argument

I want to get references to the MyObjectClass instance passed to "somePrivateMethod" called by myMock.
Now I use the following snippet but I'm sure there is a better way.
namespace {
MyObjectClass *myObjectPtr;
ACTION( getIt )
{
myObjectPtr = &arg0;
}
}
...
...
EXPECT_CALL( *myMock, somePrivateMethod( testing::_ ) ).WillOnce( testing::WithArg< 0 >( getIt( ) ) );
My problem is clearly stated I need to get the reference to that argument. The reason for what I want it has no matter here. I only need to know how to set a pointer to the argument of the somePrivateMethod.
One of the way to do this is write public get method in declaration of class A
public:
const int * get_b { return &b; }
But since you want to check the value of this variable you don't need a pointer and can return value of variable in get function
public:
int get_b { return b; }

Expand scope of a variable initialized in a if/else sequence

I'm writing a piece of code in which I'd like to use a different constructor of a class depending on a condition. So far I've used if and else statements to construct the object, but the instance is then 'trapped' in the brackets and can't be used further in the code.
Here is what it looks like in code:
if (my_boolean){
MyClass my_object(arg1); //calling a first constructor
}
else {
MyClass my_object(arg1,arg2); //calling another constructor
}
//more code using my_object
I tried using the static keyword without success so far. Is there a common way of conditionally using different constructors without having to redefine the constructors?
try the following :)
MyClass my_object = my_boolean ? MyClass(arg1) : MyClass(arg1,arg2);
Take into account that this code will work even if the class has no default constructor.
Here is a demonstrative example
#include <iostream>
#include <cstdlib>
#include <ctime>
int main ()
{
struct Point
{
Point( int x ) : x( x ) {}
Point( int x, int y ) : x( x ), y( y ) {}
int x = 0;
int y = 0;
};
std::srand( ( unsigned )std::time( 0 ) );
Point p = std::rand() % 2 ? Point( 1 ) : Point( 1, 2 );
std::cout << "p.x = " << p.x << ", p.y = " << p.y << std::endl;
return 0;
}
I have gotten the following output
p.x = 1, p.y = 2
What output have you gotten? :)
If you want to use a variable outside of a given scope, it must be declared outside that scope.
void foo()
{
MyClass my_object;
if (my_boolean){
my_object = MyClass(arg1); //calling a first constructor,
//then copy or move assignment
}
else {
my_object = MyClass(arg1,arg2); //calling another constructor,
//then copy or move assignment
}
//more code using my_object
}
//Can no longer access my_object
If you want to do it this way, I suggest defining a move assignment operator if the default will not work for your purposes (or there isn't a default move assignment operator).
Also, the code where you are using my_object may be cleaner if you move the if/else blocks and object construction to a separate function, then do something like:
MyClass my_object = make_object(my_boolean);
Or, if arg1 and arg2 aren't global,
MyClass my_object = make_object(my_boolean, arg1, arg2);
If creating an object gets more complicated than what you've asked about here, you may wish to look into the factory pattern.
You can use a smart pointer instead of a direct instance:
std::unique_ptr<MyClass> my_object;
if (my_boolean) {
//calling a first constructor
my_object.reset(new MyClass(arg1));
}
else {
//calling another constructor
my_object.reset(new MyClass(arg1,arg2));
}
//more code using my_object
In contrast to some other solutions proposed here, this will also work for bigger if() {} else if() {} sequences, or switch blocks.
In case you can't use a compiler capable of the latest standard, you can use the good old std::auto_ptr in the exactly same manner.
"I tried using the static keyword without success so far."
Good so! A static variable is certainly not what you want here.

C++ Class design - easily init / build objects

Using C++ I built a Class that has many setter functions, as well as various functions that may be called in a row during runtime.
So I end up with code that looks like:
A* a = new A();
a->setA();
a->setB();
a->setC();
...
a->doA();
a->doB();
Not, that this is bad, but I don't like typing "a->" over and over again.
So I rewrote my class definitions to look like:
class A{
public:
A();
virtual ~A();
A* setA();
A* setB();
A* setC();
A* doA();
A* doB();
// other functions
private:
// vars
};
So then I could init my class like: (method 1)
A* a = new A();
a->setA()->setB()->setC();
...
a->doA()->doB();
(which I prefer as it is easier to write)
To give a more precise implementation of this you can see my SDL Sprite C++ Class I wrote at http://ken-soft.com/?p=234
Everything seems to work just fine. However, I would be interested in any feedback to this approach.
I have noticed One problem. If i init My class like: (method 2)
A a = A();
a.setA()->setB()->setC();
...
a.doA()->doB();
Then I have various memory issues and sometimes things don't work as they should (You can see this by changing how i init all Sprite objects in main.cpp of my Sprite Demo).
Is that normal? Or should the behavior be the same?
Edit the setters are primarily to make my life easier in initialization. My main question is way method 1 and method 2 behave different for me?
Edit: Here's an example getter and setter:
Sprite* Sprite::setSpeed(int i) {
speed = i;
return this;
}
int Sprite::getSpeed() {
return speed;
}
One note unrelated to your question, the statement A a = A(); probably isn't doing what you expect. In C++, objects aren't reference types that default to null, so this statement is almost never correct. You probably want just A a;
A a creates a new instance of A, but the = A() part invokes A's copy constructor with a temporary default constructed A. If you had done just A a; it would have just created a new instance of A using the default constructor.
If you don't explicitly implement your own copy constructor for a class, the compiler will create one for you. The compiler created copy constructor will just make a carbon copy of the other object's data; this means that if you have any pointers, it won't copy the data pointed to.
So, essentially, that line is creating a new instance of A, then constructing another temporary instance of A with the default constructor, then copying the temporary A to the new A, then destructing the temporary A. If the temporary A is acquiring resources in it's constructor and de-allocating them in it's destructor, you could run into issues where your object is trying to use data that has already been deallocated, which is undefined behavior.
Take this code for example:
struct A {
A() {
myData = new int;
std::cout << "Allocated int at " << myData << std::endl;
}
~A() {
delete myData;
std::cout << "Deallocated int at " << myData << std::endl;
}
int* myData;
};
A a = A();
cout << "a.myData points to " << a.myData << std::endl;
The output will look something like:
Allocated int at 0x9FB7128
Deallocated int at 0x9FB7128
a.myData points to 0x9FB7128
As you can see, a.myData is pointing to an address that has already been deallocated. If you attempt to use the data it points to, you could be accessing completely invalid data, or even the data of some other object that took it's place in memory. And then once your a goes out of scope, it will attempt to delete the data a second time, which will cause more problems.
What you have implemented there is called fluent interface. I have mostly encountered them in scripting languages, but there is no reason you can't use in C++.
If you really, really hate calling lots of set functions, one after the other, then you may enjoy the following code, For most people, this is way overkill for the 'problem' solved.
This code demonstrates how to create a set function that can accept set classes of any number in any order.
#include "stdafx.h"
#include <stdarg.h>
// Base class for all setter classes
class cSetterBase
{
public:
// the type of setter
int myType;
// a union capable of storing any kind of data that will be required
union data_t {
int i;
float f;
double d;
} myValue;
cSetterBase( int t ) : myType( t ) {}
};
// Base class for float valued setter functions
class cSetterFloatBase : public cSetterBase
{
public:
cSetterFloatBase( int t, float v ) :
cSetterBase( t )
{ myValue.f = v; }
};
// A couple of sample setter classes with float values
class cSetterA : public cSetterFloatBase
{
public:
cSetterA( float v ) :
cSetterFloatBase( 1, v )
{}
};
// A couple of sample setter classes with float values
class cSetterB : public cSetterFloatBase
{
public:
cSetterB( float v ) :
cSetterFloatBase( 2, v )
{}
};
// this is the class that actually does something useful
class cUseful
{
public:
// set attributes using any number of setter classes of any kind
void Set( int count, ... );
// the attributes to be set
float A, B;
};
// set attributes using any setter classes
void cUseful::Set( int count, ... )
{
va_list vl;
va_start( vl, count );
for( int kv=0; kv < count; kv++ ) {
cSetterBase s = va_arg( vl, cSetterBase );
cSetterBase * ps = &s;
switch( ps->myType ) {
case 1:
A = ((cSetterA*)ps)->myValue.f; break;
case 2:
B = ((cSetterB*)ps)->myValue.f; break;
}
}
va_end(vl);
}
int _tmain(int argc, _TCHAR* argv[])
{
cUseful U;
U.Set( 2, cSetterB( 47.5 ), cSetterA( 23 ) );
printf("A = %f B = %f\n",U.A, U.B );
return 0;
}
You may consider the ConstrOpt paradigm. I first heard about this when reading the XML-RPC C/C++ lib documentation here: http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#constropt
Basically the idea is similar to yours, but the "ConstrOpt" paradigm uses a subclass of the one you want to instantiate. This subclass is then instantiated on the stack with default options and then the relevant parameters are set with the "reference-chain" in the same way as you do.
The constructor of the real class then uses the constrOpt class as the only constructor parameter.
This is not the most efficient solution, but can help to get a clear and safe API design.

Call public member with **ClassObject ( C++ )

I need to call my public member. The Constructor that takes 1 paramater.
This is how my code looks:
// main
char tmpArray[100] = {};
while ( !inFile.eof() )
{
for ( unsigned x = 0; x < str2.length(); x++ )
{
if ( !isspace( str2[x] ) || isspace( str2[x] ) )
{
tmpArray[x] = str2[x]; // prepare to supply the constructor with each word
ClassObject[wrdCount] = new ClassType[x] ;
//ClassObject[wordCount]->ClassType( tmpArray );
}
}
}
The error is:
'function-style cast' : illegal as
right side of '->' operator
To try and resolve the issue i try two equivalent expressions:
/* no good */ (*ClassObject[wrdCount]).ClassType( tmpArray );
/* no good */ (*ClassObject[wrdCount][10]).ClassType( tmpArray );
/* combine */ ClassObject[arbitrary][values]->ClassType( tmpArray );
Intellisense does brings up all my members and privates except the constructor..
Could this be the reason?
//MyHeader.h
class ClassObject
{
private:
const char* cPtr;
float theLength;
public:
ClassObject( const char* ); // Yes its here and saved..
ClassObject(); // an appropriate default constructor
~ClassObject( );
char GetThis( );
char* GetThat( );
}
I am assuming the following things as it is not clear from the code posted:
(1). ClassObject is defined like this: ClassType* ClassObject[/some value/10];
(2). The class definition in MyHeader.h is of ClassType and not of ClassObject.
In such a case, the following statement is the problem:
ClassObject[wrdCount] = new ClassType[x]
Here it creates 'x' number of ClassType objects. I don't think thats what you want. I guess you want to construct a ClassType object by passing const char* as the constructor parameter. If that is so you should use it like this:
ClassObject[wrdCount] = new ClassType(tmpAray);
Also note that you are assuming size of the array passed. I suggest it is better to use something like a std::string instead of raw character arrays.
I'm not entirely clear on what you're doing, but you cannot explicitly call a constructor like that. If you have a pointer-to-a-pointer-to-a-ClassType called ClassObject, you need to do something like this to initialize it:
ClassObject[wrdCount] = new ClassType*[x]; // create a new 'row' in the array with x columns
for (int i = 0; i < x; ++i) // initialize each 'column' in the new row
ClassObject[wrdCount][i] = new ClassType(tmpArray);
This doesn't seem to make much sense given the code you have pasted though (since wrdCount doesn't change). It's hard to say without an exact problem description.
You need to use identifiers. The following:
ClassObject[wrdCount] = new ClassType[x] ;
tries to apply the operator[] to a class type name. What good can that do? None. Try:
ClassObject *a = new ClassType[x];
This'd create an object a of type array of size x of Classtypes. Do you need an array here -- it's upto you. If all you need is a single variable use:
ClassObject *a = new ClassType;