I have a class and a function that returns an object of that class, if i return NULL what exactly gets returned?
Example:
class someclass {
int a;
int b;
someclass::someclass(int a, int b) {
this->a = a; this->b = b;
}
};
someclass functionname() {
return NULL;
}
someclass foo = functionname();
Since I dont have a default constructor for the class what gets returned? Is it an actual usable object? Or just gibberish? Why cant I check like this?
if (foo == NULL) {
something
}
In C++, there is no actual null (however there is nullptr since new versions).
This means that NULL is defined like that:
#define NULL 0
So that it has the same qualities as 0, number variable, has. That's why you can't set your class to 0.
Compiler won't accept this code. C++ unlike Java and C# does not treat class instances as pointers (or references). So, for this return it will try to create new instance of someclass with the code someclass(NULL). Since you have no appropriate constructor, an error will occur.
If you want to have some "absent" values for the class, either program it inside class (for example, as boolean flag) or use pointers, for example:
someclass* functionname() {
if( ??? ) {
return new someclass(2,3);
}
else {
return NULL;
}
}
remember that C++ does not have grabage collector, so you will need to delete newed object yourself when not needed.
someclass *a;
a = functionname();
...
delete a;
forgetting this is most annoying error in C++.
The example is more of a situational description than something that should actually compile hence i didn't bother verifying it since it has nothing to do with the answer anyway and i doubt anybody would be interested in sifting through 100 lines of me defining a class and a function.
Anyway the answer is that if the class has any constructors that take 1 variable (optionally or otherwise) it will use that constructor and initialize the object with 0 in the first variable it can fit into
Related
I want to initialize member object variables in the default constructor of the class.
Let's consider the following,
class ABC {
ABC(int A, int B) {
a = A;
b = B;
}
int a;
int b;
};
class Foo {
Foo();
ABC m_obj1;
};
From the above example, I would like to initialize "obj1" in "Foo::Foo()".
One of the restrictions I have is that I cannot do so in the initializer list, as I need to do some computation before I could initialize the member. So the option available (ASFAIK) is to do so in the body of the default constructor only.
Any inputs, how could I do this?
Edit: Restricting to C++11
Would this be a correct way,
Foo:Foo() {
int x = 10;
int y = 100;
m_Obj1(x, y); //Is this correct? <--------
}
Depending on your exact problem and requirements, multiple solutions might be available:
Option 1: Use a function to do the computations and call Foo constructor
Foo makeFoo()
{
// Computations here that initialize A and B for obj1 constructor
return Foo(A, B)
}
Option 2: Call a function that does the computations and initialize obj1 in Foo member initializer list
ABC initABC() {
// Some computations
return ABC(A, B)
}
Foo() : obj1(initABC()) {}
Option 3: Dynamically allocate obj1, for instance with a std::unique_ptr
Option 4: Use std::optional or an emulated c++11 version as shown by other answers
You simply call the base constructor inside the initializer list of the derived constructor. The initializer list starts with ":" after the parameters of the constructor. See example code!
There is no problem to call functions inside the initializer list itself.
int CallFunc1(int x) { return x*2; }
int CallFunc2(int y) { return y*4; }
class ABC {
public:
ABC(int A, int B):a{CallFunc1(A)},b{CallFunc2(B)} {
std::cout << "Constructor with " << a << " " << b << " called" << std::endl;
}
private:
int a;
int b;
};
class Foo {
public:
Foo(): obj1(1,2){}
Foo( int a, int b): obj1(a, b){}
private:
ABC obj1;
};
int main()
{
Foo foo;
Foo fooo( 9,10);
}
edit:
The best method I can think of for your case is a copy constructor, being more specific on what you need to store helps a lot since if it is just two ints inside a class dynamic allocation is not worth it, the size of the object being constructed makes a difference to what method is best, copy constructors can be slower with much larger data types as the object has to be created twice: once when it is automatically constructed in the parent objects constructor and again when a temporary object is created and all the values have to be copied, which can be slower then dynamically allocating if the size is larger.
As far as I'm aware all objects in a class are automatically initialized/allocated in the constructor so sadly dynamic memory use may be your best bet here.
If you are fine with having the object initialized but empty so you know it is not 'ready' yet you can later fill it with useful data when you would have wanted to initialize it. This can be done with default constructors that set the things inside the object to null values or something similar so you know the object hasn't been properly initialized yet. Then before using the object you can check whether it has been initialized by checking for the null values or by having put a bool in the object that tells you whether it is initialized. Dynamically allocated would still be better in my opinion and makes the code look cleaner overall as all you need to store is a null pointer until the object is needed and then allocated and set to the pointer. It is also very easy to check if the pointer is equal to nullptr to know the state of your object.
Dynamically allocating memory may be a hassle since you have to make sure to get rid of memory leaks and it is slightly slower than using the stack, but it is a necessary skill for c++ since the stack is not enough when making programs that use more than the few available megabytes of data on the stack so if you are doing this simply to avoid the hassle I recommend learning it properly. It would be nice if you could be more specific about what kind of object you want to do this with or if you just want an answer that works for most cases.
eg:
*ABC obj1 = nullptr;
...object is needed
obj1 = new(ABC(constructor stuff));
...obj1 isn't needed
delete obj1;
or c++ automatically deletes it when the program closes.
I want to implement class which let's say have field key and class A or B.
The argument in constructor in this class is array of chars.
The constructor pseudocode would take a look at first char, if it is exual to 0x00 it will create class A object,
otherwise it will create class B object - both classes will take the array of chars as argument.
Anyway I want to keep this implementation simple. I don't want to use boost::Variant unless I really need to,
and also I don't want to implement sth like this Implementing a "variant" class
because I am not familiar with template programming and I think my problem can be implemented in much simpler way.
For POD types, we have union (but the union won't remember which type you assigned, so also store this separately). This won't work for non-POD types. The major reason is because C++ doesn't know which one it should create upon construction / delete upon deletion of the union.
But a union can be used to hold pointers to the actual types. Then you have to care about construction and deletion yourself.
You could create something like this, which wraps this pointer-union and adds a convenient interface. Detailed explanation is written in the comments:
class EitherAorB {
// We have to remember what we actually created:
enum Which {
A_Type,
B_Type
} m_which;
// We store either a pointer to an A or to a B. Note that this union only
// stores one pointer which is reused to interpret it as an A*, B* or void*:
union {
A *a;
B *b;
void *untyped; // Accessing the same pointer without looking at the type
} m_ptr;
// Additional stuff you want to store besides A and B
const char *m_key;
public:
EitherAorB(const char *key) {
// Decision: Which type do we want to create?
m_which = key[0] == 0 ? A_Type : B_Type;
// Create the type (the cast to void* make the pointer "untyped"):
m_ptr.untyped = m_which == A_Type ? (void*)new A() : (void*)new B();
// Store additional stuff
m_key = key;
}
~EitherAorB() {
// Since we stored the actual contents outside and point to them,
// we have to free the memory. For this, we have to care about the
// type again, so the correct destructor will be chosen. Deleting
// the untyped pointer won't work here.
if (m_which == A_Type) delete m_ptr.a;
if (m_which == B_Type) delete m_ptr.b;
}
// These two functions can be used to query which type is stored.
bool hasA() const {
return m_which == A_Type;
}
bool hasB() const {
return m_which == B_Type;
}
// These two functions can be used to query the pointers to the actual types.
// I made them return a null pointer if the wrong getter was used.
A *getA() {
return m_which == A_Type ? m_ptr.a : 0;
}
B *getB() {
return m_which == B_Type ? m_ptr.b : 0;
}
}
Note that this implementation will lack memory if you copy an instance of EitherAorB. To fix this, either disable copying (by making the copy constructor and assignment operator private or disable them in C++11 using = delete), or implement the copy constructor and assignment operator which will deeply copy the pointee.
You said you aren't familiar with template programming. Making this implementation templated isn't difficult. Just put template<typename A, typename B> before the whole class definition; it should then work out of the box. However, don't move the implementations in .cpp files in this case; best is to keep them inlined as I wrote it.
Then, A and B aren't types but placeholders you assign types in your client code. I'd then rename the tempalte class to just Either, so your type names become something like Either<This, That>.
I need to grab an object by reference and I used to do it like so:
MyObject& obj = FactoryThatGivesAnObject();
obj.MethodThatModifieObj();
No I need to do it based on a conditional:
MyObject obj;
// Need obj to be a reference to the returned values below
if( foo )
obj = FactoryThatGivesAnObject();
else
obj = OtherFactoryThatGivesAnObject();
obj.MethodThatModifiesObj();
How can I have obj be a reference in the second example?
References, unlike pointers, can only be set once. This is a useful feature many times, but this is the one frustrating aspect about it. You only want to set the reference once, but possibly to different things.
You have two options.
1) Use the ternary operator
This is often the easiest, if you're only dealing with two factories, and a simple boolean to decide which to use:
MyObject& obj = ( foo
? FactoryThatGivesAnObject();
: OtherFactoryThatGivesAnObject() );
However, if foo is more complicated, or if you have multiple factory options, the next option may be cleaner.
2) Use a factory method of your own
MyObject& get_an_object(const int state) // or whatever parameters you need
{
switch(state)
{
case USE_LEGACY_FACTORY: return FactoryThatGivesAnObject();
case USE_FOO_FACTORY: return OtherFactoryThatGivesAnObject();
case DO_SOMETHING_ELSE: return YetAnotherObjectFactory();
}
throw std::runtime_error("Bad Factory Selector");
}
// usage is simpler now
MyObject& obj = get_an_object(foo);
Note that you may need to pass several parameters to your factory method:
selection criteria. Your example was just foo - a simple boolean. As things grow, you may need additional criteria to help determine which factory to use.
factory objects. You may have factory objects instead of factory methods, in which case you need to pass references to those objects into your method.
One solution may be to use a ternary operator:
obj = foo ? FactoryThatGivesAnObject() : OtherFactoryThatGivesAnObject();
You could also use a pointer:
MyObject* pobj;
if( foo )
pobj = &FactoryThatGivesAnObject();
else
pobj = &OtherFactoryThatGivesAnObject();
Your very first line is shady:
MyObject& obj = FactoryThatGivesAnObject();
How is that supposed to work? The factory method cannot return a reference to a temporary, so the only sensible reference it could return is to a dynamically created object - but now who is responsible for this object?
(Unless you are just returning a reference to an existing object, that is. But I'm assuming that your factory is genuinely creating new objects.)
This code is a memory-leak car crash; I don't see any way to write anything sensible like that. A far better way is to return the newly created object in a responsible container, e.g. a shared_ptr or a unique_ptr:
#include <memory>
std::unique_ptr<MyObject> FactoryFunction()
{
return std::unique_ptr<MyObject>(new MyObject(3,5,7));
}
That way, if nobody picks up the factory product, or if an exception occurs, the dynamically allocated object will get properly disposed of.
This also makes it trivial to assign different pointers depending on a conditional:
std::unique_ptr<MyObject> x;
if (...) { x = Factory1(); }
else if (...) { x = Factory2(a,b); }
else { x = Factory3(argc, argv); }
How can I have obj be a reference in the second example?
You can't. References are aliases; you can only create them by pointing them at something, and once you've pointed them, they cannot be reassigned.
You would probably be better off using something like a std::auto_ptr or std::unique_ptr here. Note that your factory would need to return the auto/unique_ptr though. If your factory is returning a reference I suspect you might be accidentially returning references to unnamed temporaries (unedefined behavior), but without seeing the factories' code it's difficult to tell.
Here's one solution which is not technically a factory, but solves the same problem -- providing new objects when you change parameters:
struct A
{
int a;
float x;
int c;
};
class ObjectCollection
{
public:
ObjectCollection() { m_a.c = 10; }
A &get_obj_a(int a, float x)
{
m_a.a = a;
m_a.x = x;
return m_a;
}
private:
A m_a;
};
This version has advantage that it does not pass around ownership to the object, but still you can create different kinds of objects with it. Two calls to get_obj_a() will cause problems though, it only works if you call get_obj_a() immediately before you need the object. Now the if statement can be put inside the factory function. Also here's another way to do it:
class DerivedFactory
{
public:
DerivedFactory(ObjectCollection1 &c, ObjectCollection2 &c2) : c(c),c2(c2) { }
Base &get_obj_a_or_b(bool b) {
if (b) return c.get_obj_a(10,11.0);
else return c2.get_obj_b(20.0,13.0);
}
private:
ObjectCollection1 &c;
ObjectCollection2 &c2;
};
I need the flexibility of being able to change parameters passed around to different functions, depending from where the call to the function happened, so I decided I'd put all my parameters in a struct, however most of these parameters are structs or classes themselves and I want to have the option of leaving them NULL, so I have to pass pointers to the structs/classes.
struct A
{
otherB* b; // NULL should be a valid value
otherC* c;
};
However my question is now, passing A around these pointers will be the only thing copied, so if I did the following there would be a problem right?
void func(A& a) //non const cause I wanna change contents of A.
{
a.b = new b();
}
A myA;
otherC somec; // all these are currently automatic variables in my pgm.
myA.c = &somec;
func(myA); //myA goes out of scope? so I've lost all pointers assigned and since somec is out of scope too, I have a problem?
What would the best way to resolve something like this+ I want the flexibility of being able to pass NULL to any of my parameters, however not sure if using raw pointers everywhere is a good idea?
To solve the problem of resource management, you should use boost::shared_ptr (or std::shared_ptr in C++0x).
struct A
{
boost::shared_ptr< otherB > b;
boost::shared_ptr< otherC > c;
};
void func(A& a)
{
a.b = boost::make_shared< otherB >();
}
A myA;
otherC somec;
myA.c = boost::shared_ptr< otherC >(&somec, null_deleter());
func(myA);
When myA goes out of scope, all resources are deallocated automatically. Since somec was allocated on the stack, we wrapped it in a shared_ptr that uses a null_deleter, that could look like this:
struct null_deleter {
void operator()(void *) { }
};
This will not delete the object, it will do nothing (which is just what we want for stack-allocated objects). Keep in mind however, that you have to make sure that somec lives longer than myA, otherwise you will get access violations.
boost::optional<> Allows you to test if the field is set or not.
Simple example (will not compile, I've not even remotely tested it, in theory this is how it should work)
struct params
{
boost::optional<int> a;
boost::optional<foo> b;
boost::optional<bar> c;
};
void func(params& p)
{
if (p.a)
{
// do stuff with a
}
if (p.b)
{
// do stuff with b
}
if (p.c)
{
// do stuff with c
}
else
p.c = bar(); // again copy constructed and now initialized...
}
params p;
p.a = 1;
p.b = foo(); // copy constructed, however you can store a reference in the optional too.
// c is uninitialized
func(p);
// when p goes out of scope, everything is gone..
You basically have to analyze ownership, i.e. who can allocate and who is responsible for deleting object once they no longer is used.
One thing that is important to remember is that if you mix dynamically allocated things and things placed on the stack, you simply can't apply delete on them, as it's not possible to delete things on the stack.
One way could be to only use new and define a destructor in A that deletes all it's pointers. Another way could be a place where you would register objects that later should be deleted. Or you could go the route of using existing reference-counting tools, as suggested in other answers.
No, your idea of the scope of myA and somec are wrong. There's nothing wrong with what you have right now- although I personally think that references would be a superior option to pointers.
void func(A& a) //non const cause I wanna change contents of A.
{
a.b = new b();
}
int main() {
A myA;
otherC somec; // all these are currently automatic variables in my pgm.
myA.c = &somec;
func(myA);
// myA and somec are still perfectly in scope to be saved, or deleted, or w/e as you like
}
It's not clear from your description, but if you're having a problem
because somec is going out of scope, it can only be because func is
saving a copy of the pointer. Don't do that: in funct, copy the object,
not the pointer.
PS: if most of the pointers are null most of the time, you should
consider using something like following syntactic sugar:
struct A
{
// pointer members...
A() : // ... set all pointers to null...
A& withB( B const& someB ) { otherB = &someB; return *this ; }
A& withC( C const& someC ) { otherC = &someC; return *this ; }
// And so on for all of the rest of the pointers.
};
func( A().withC( somec ) );
Don't know if it's appropriate for your situation, but it's often
convenient.
I have two methods to create an instance for a pointer.
But one of them will fail.
class A {
public:
int num;
};
void testPointer1(A* a){
a = new A();
a->num = 10;
}
A* testPointer2(){
A* a = new A();
a->num = 10;
return a;
}
void testPointer() {
A* a1 = NULL;
testPointer1(a1); // this one fails
//cout << a1->num << endl; // segmentation fault
A* a2 = NULL;
a2 = testPointer2();
cout << a2->num << endl;
}
why is testPointer1 wrong?
The syntax is valid, but it doesn't do what you want because testPointer1() is operating on a copy of the pointer, not the actual pointer itself. So when you assign the address to the newly allocated object, it gets assigned to the copy, not to the original a1 pointer.
Because of this, the address is lost and you get a memory leak. Also, since the original a1 pointer was never modified in the first place, you attempted to dereference a null pointer, which is a bad thing.
I'd say testPointer2() is the better way to do it, but if you want testPointer1() to work, try this:
void testPointer1(A*& a)
{
a = new A();
a->num = 10;
}
The parameter type indicates "a reference to a pointer to A." That way, instead of a copy of the pointer being passed, a reference to the original pointer will be passed. A C++ reference is an alias to another object. So whatever you do on the alias, it gets performed on the original object.
Extra notes:
Note that the parentheses in new A(); are actually significant and their presence or absence makes a difference.
Also note that you must manually delete all new'ed objects after you're done with them, or you will get a leak. Typically you would wrap the pointer in its own class and implement RAII or use a smart pointer such as Boost's smart pointers or auto_ptr, for proper memory management and exception safety.
If you're going to set the value of num on initialization, why not create a constructor?
class A
{
public:
A(int n) : num(n) {}
int GetNum() const { return num; }
private:
int num;
};
void testPointer1(A*& a)
{
a = new A(10);
}
A* testPointer2()
{
return new A(10);
}
// auto_ptr example, see link in second note above
std::auto_ptr<A> testPointer3()
{
return auto_ptr<A>(new A(10));
}
The testPointer1 functions works on a copy of the provided pointer : modifications to a in testPointer1 are not reflected to the caller.
It's exactly like in this simpler example :
void testInt1(int i)
{
i++;
}
void testInt()
{
int i = 0;
testInt1(i);
// i is still 0
}
If you want the change in testInt1 to be reflected to the caller, you have to pass either a pointer or reference to i (and not just the value of i). The same solution can be applied to your specific case, though one could argue that pointers to pointer and references to pointer are not really a best practice.
Is this homework ?
This seems to be obvious:
formal parameters are saved on the stack & restored after method/function call.
then whatever f(type x), manipulating x inside the function/method won't change it's value outside of the function.
even if type is a pointer type.
the only way to make x change inside a function is to tell it is modifiable through references or pointer to type.
in your case :
A* a1 =NULL
call to your method won't change value of a1 outside of testPointer1
so a1 will still be NULL after the call.