#include <iostream>
struct something{
int i;
something(int i) : i(i) {}
};
class otherthing {
otherthing(){}
static something foo(int value)
{
return { value };
}
};
In this example what the foo function returns? Am I understand correctly that it creates an object on the heap and returns a pointer? Is this considered bad style? Or is it ok for structs and not classes?
I can feel that it might be a stupid question but I tried to google it and I could not find the answer. I apologize in advance if this is dumb.
In this example what the foo function returns?
Object of type something, initialized with value value.
Am I understand correctly that it creates an object on the heap and returns a pointer?
No. It creates an object with automatic lifetime (typically associated with stack memory). It returns that object and no pointer.
Is this considered bad style?
It's quite useless in this example, but in general this approach is called factory pattern. It allows you to separate creation of object from other logic, and that would be good style actually.
Or is it ok for structs and not classes?
The only difference between struct and class in C++ is the default access modifier. In struct member are by default public, in class members are by default private.
Am I understand correctly that it creates an object on the heap and returns a pointer?
No, it does not return a pointer, it returns an instance of something with automatic storage duration (which is commonly allocated on the stack) which for the return will utilize copy elision
Or is it ok for structs and not classes?
A struct and a class only differ in the default access modifier, besides that there is no difference.
In C++ (unlike C#) classes and structs are identical but for one tiny detail: the default access level for a class is private; for a struct it's public.
In your example, a something object is created on the stack in foo. When foo is called, e.g.
something s = otherthing.foo();
then the object is copied into s on the stack.
No pointers are involved.
Related
I'm studying the C++ class method pointers and I've crossed this example:
class A
{
public:
A();
void sample() { ...method_stuff... }
void (A::*ptrToSample);
};
A::A()
{
ptrToSample = &A::sample;
}
Now, if I've understood correctly, sample is non-static, which means that I can't invoke it without an object of A, more precisely, if I do not create an object of A, also all its non-static methods and members aren't stored in memory either.
Having said so, I get confused by the object constructor reported by the example. Shouldn't any object of A have a copy of sample? If yes, then why I have to use the & operator on the class scope instead of this operator?
Shouldn't the constructor be something like:
{
ptrToSample = &(this->sample);
}
?
Since the method is non-virtual, it shouldn't be saved in the virtual method table (right?), then where the heck is it stored? What am I missing?
Thanks for the help !
First, void (A::*ptrToSample); must be void (A::*ptrToSample)();.
sample is non-static, which means that I can't invoke it without an object of A
Yes.
more precisely, if I do not create an object of A, also all its non-static methods and members aren't stored in memory either
No, methods aren't stored in objects. There's always a single "instance" of each method in memory, and it isn't copied when you create objects. Under the hood, methods work like regular (free) functions, but with an implicit this parameter.
Shouldn't the constructor be something like: ptrToSample = &(this->sample);
It's hard to say why a specific syntax was choosen, but &(this->sample) would be somewhat misleading, since a member pointer doesn't contain a pointer to a specific object instance (so this would be discarded). You don't have to have an object to create a member pointer. The object needs to be provided later, when you dereference the pointer.
// Example program
#include <iostream>
class Foo{
public:
Foo(int a):a(a){}
void print(){
printf("%d\n",a);
}
private:
int a;
};
class Bar{
public:
Bar(Foo* foo):foo(foo){}
void print(){
foo->print();
}
private:
Foo* foo;
};
int main()
{
Foo f = {10};
Bar b(&f);
b.print();
f = {20};
b.print();
}
In the code above a Foo object shared with a Bar object can be recreated without that Bar knows about it.
Imagine I have to inject the bar object into a third class. Now I can update the foo dependency without having to create a new object of bar and the third class.
Is this pattern commonly used or not and does it violate some of the OOP principles?
I don't think the code does what you think it does.
I've added the default constructors and assign/operators to your Foo class with some logging to see what happens. These constructors are added automatically by the compilers unless you disable them explicitly. See the output here.
What happens in
f = {20};
is that you construct a different Foo object then you move-assign it to the original instance.
In this case it's equivalent to
f.a = 20; // Assuming we make a public.
In conclusion.
If your usage is just to change fields in the existing instance (through assign operators in this case). Then everything should work fine. This shouldn't necessarily invalidate OOP principles, unless you have assumptions that Bar.foo is constant or doesn't change. This is usually called composition and it's fairly common (your UI will contain various button instances that might be modified from other sources).
If you expect to change the implementation (say Foo is a virtual class and you want a different derivation to be substituted) then in your code you will need to have Foo* f = new Foo(10);. You will have copy of the pointer in b and the assignment will create a new class, that will not be update in b (something like f = new FooDerived(20);.
To make it work you need a Provider class (this is a OOP pattern). This would be something that gives you a Foo. The simplest one would be Foo**. But it's likely better to have something a bit more customizable.
That said for any serious work try to stay away from naked pointers (Foo*). Use unique_ptr or shared_ptr as appropriate to save yourself a lot of problems in the future.
Is this pattern commonly used or not and does it violate some of the OOP principles?
Yes, this is fairly common, and OK in your example.
You do have to be careful to ensure that f remains alive for the whole lifetime of b, which is the case in your example. If you were to copy b, you would also need to ensure the copy didn't outlive f.
The nice thing about the local variables of a function func is that they outlive any local variables of functions that func calls. Thus the local variables of main live for (almost) the whole program, only global variables outlive them.
Is this pattern commonly used or not and does it violate some of the OOP principles?
I would say that such a structure should be carefully used.
Actually, in Bar you are just copying the pointer value. But if the given Foo created on the stack goes out of scope, then Bar is storing a dangling pointer.
Trying to dereference a dangling pointer is Undefined Behaviour.
Is it bad to recreate stack object after injected to class as pointer?
Actually, as #DanielLangr mentioned, you did not have "recreated" the object, you just have reassigned its contents, so the object lifetime has not ended.
In your case, you're still fine.
look at my code:
#include <iostream>
using namespace std;
class MyClass{
public:
char ch[50] = "abcd1234";
};
MyClass myFunction(){
MyClass myClass;
return myClass;
}
int main()
{
cout<<myFunction().ch;
return 0;
}
i can't understand where my return value is stored? is it stored in stack? in heap? and does it remain in memory until my program finished?
if it be stored in stack can i be sure that my class values never change?
please explain the mechanism of these return. and if returning structure is different to returning class?
MyClass myClass; is stored on the stack. It's destroyed immediately after myFunction() exits.
When you return it, a copy is made on the stack. This copy exists until the end of the enclosing expression: cout << myFunction().ch;
Note that if your compiler is smart enough, the second object shouldn't be created at all. Rather, the first object will live until the end of the enclosing expression. This is called NRVO, named return value optimization.
Also note that the standard doesn't define "stack". But any common implementation will use a stack in this case.
if returning structure is different to returning class?
There are no structures in C++; keyword struct creates classes. The only difference between class and struct is the default member access, so the answer is "no".
It's up to the implementation to find a sensible place to store that value. While it's usually on the stack, the language definition does not impose any requirements on where it's actually stored. The returned value is a temporary object, and it gets destroyed at the end of the full statement where it is created; that is, it gets destroyed at the ; at the end of the line that calls myFunction().
When you create an object in any function it's destroyed as soon as the function execution is finished just like in variables.
But when you return a object from a function firstly compiler creates a local instance of this object in heap called unnamed_temporary then destroyes the object you created. And copies the contents of unnamed_temporary on call. Then it destroyes this unnamed _temporary also.
Anything you create without the keyword new will be created in stack.
Yes,contets of your variable ch will not change unless you access that variable and change it yourself.
The instance returned by myFunction is temporary, it disappears when it stop to be useful, so it doesn't exist after after the cout <<.... Just add a destructor and you will see when it is called.
What do you mean about can i be sure that my class values never change? ? You get a copy of the instance.
returning structure is different to returning class? : a struct is like a class where all is public by default, this is the alone difference.
Your function is returning a copy of an object. It will be stored in the stack in memory.
The returning obj. will exist until the scope of that function. After that, it will be destroyed. Then, your expression cout<<function(); will also have the copy of that obj. which is returned by the function. IT will be completely destroyed after the running of this cout<<function(); expression.
I recently reworked one of my own libraries to try out separating interface from implementation. I am having on final issue with a class that is meant to return an instance of another class.
In the interface definition, I do something like
struct IFoo
{
virtual const IBar& getBar() = 0;
}
and then in the concrete Foo getBar looks like
const IBar& Foo::getBar()
{
Bar ret = Bar();
return ret;
}
The problem is ret gets deleted as soon as getBar is done, causing a big crash when the copy constructor tries to use Bar like so
const Bar myBar = myFoo.getBar();
I have been reading various things, and I know returning by reference is frowned upon, but I do not see any other way (I do not want to return Bar* because I do not want to have to manually delete the return value).
What is the proper way (if any way exists) for an abstract class to return an instance of a concrete class derived from another abstract class?
Note I did see this solution: returning an abstract class from a function
but I do not want to make the return value static and loose thread safety.
Use smart pointers.
These are pointers deleted when not used anymore (see for example http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/smart_ptr.htm).
You can also return the object by value.
Some compilers provide the Return value optimization which optimize away the copy when returning an object.
Edit:
Sorry. I skimmed through the question and somehow missed the fact that inheritance is involved. Assuming that getBar() can return various kind of IBar returning an IBar pointer makes a lot of sense.
By returning a pointer to base the concrete object is kept intact. The slicing problem is avoided and the original vtbl pointer is available to make virtual function calls. Also (as you noted in your comment) returning an instance of an abstract class is just impossible.
Instead of returning a raw pointer I suggest you return a shared_ptr<IBar> to simplify memory management.
const shared_ptr<IBar> Foo::getBar()
{
shared_ptr<IBar> ret(new Bar());
return ret;
}
Then use it this way:
shared_ptr<IBar> pIBar(foo.getBar());
pIBar->myVirtualFunction();
shared_ptr is the most commonly used smart pointer type in C++0x. If you have a sufficiently recent compiler it will be in the std namespace. Older compiler may have it in the tr1 namespace and it's also part of boost.
You're returning a reference to a local variable. As soon as the function returns the reference, the stack gets popped and that Bar object ceases to exist.
EDIT: I didn't read the whole thing. You'll probably need to use a smart pointer.
Actually, is there any reason why you need to return a base class reference? You could avoid any smart pointer messiness by returning an object of the concrete type itself, since C++ allows covariant return types.
Since you want to transfer ownership of the returned object to the caller, the caller will have to destroy the object. In other words, returning IBar * is your best bet. If you are worried about having to manually call delete, you should look into using a smart pointer package, e.g. boost::shared_ptr.
If you don't want to take care of deletion then you have to use SmartPointers.
In C++ this is the only way to have object "deletes itself" when it is appropriated.
http://en.wikipedia.org/wiki/Smart_pointer
The object that has been created on the stack will be destructed when your stack is removed. The stack is removed when the function exits.
Instead, try something like this:
struct Foo : public IFoo
{
Bar m_Bar;
public:
virtual const IBar& getBar()
{
return m_Bar;
}
}
After reading a question on the difference between pointers and references, I decided that I'd like to use references instead of pointers for my class fields. However it seems that this is not possible, because they cannot be declared uninitialized (right?).
In the particular scenario I'm working on right now, I don't want to use normal variables (what's the correct term for them by the way?) because they're automatically initialized when I declare them.
In my snippet, bar1 is automatically instantiated with the default constructor (which isn't what I want), &bar2 causes a compiler error because you can't use uninitialized references (correct?), and *bar3 is happy as larry because pointers can be declared uninitialized (by the way, is it best practice to set this to NULL?).
class Foo
{
public:
Bar bar1;
Bar &bar2;
Bar *bar3;
}
It looks like I have to use pointers in this scenario, is this true? Also, what's the best way of using the variable? The -> syntax is a bit cumbersome... Tough luck? What about smart pointers, etc? Is this relevant?
Update 1:
After attempting to implement a reference variable field in my class and initializing it in the constructor, why might I receive the following error?
../src/textures/VTexture.cpp: In constructor ‘vimrid::textures::VTexture::VTexture()’:
../src/textures/VTexture.cpp:19: error: uninitialized reference member ‘vimrid::textures::VTexture::image’
Here's the real code:
// VTexture.h
class VTexture
{
public:
VTexture(vimrid::imaging::ImageMatrix &rImage);
private:
vimrid::imaging::ImageMatrix ℑ
}
// VTexture.cpp
VTexture::VTexture(ImageMatrix &rImage)
: image(rImage)
{
}
I've also tried doing this in the header, but no luck (I get the same error).
// VTexture.h
class VTexture
{
public:
VTexture(vimrid::imaging::ImageMatrix &rimage) : image(rImage) { }
}
Update 2:
Fred Larson - Yes! There is a default constructor; I neglected it because I thought it wasn't relevant to the problem (how foolish of me). After removing the default constructor I caused a compiler error because the class is used with a std::vector which requires there to be a default constructor. So it looks like I must use a default constructor, and therefore must use a pointer. Shame... or is it? :)
Answer to Question 1:
However it seems that this is not possible, because they [references] cannot be declared uninitialized (right?).
Right.
Answer to Question 2:
In my snippet, bar1 is automatically
instantiated with the default
constructor (which isn't what I want),
&bar2 causes a compiler error because
you can't use uninitialized references
(correct?),
You initialize references of your class in your constructor's initializer list:
class Foo
{
public:
Foo(Bar &rBar) : bar2(rBar), bar3(NULL)
{
}
Bar bar1;
Bar &bar2;
Bar *bar3;
}
Answer to Question 3:
In the particular scenario I'm working
on right now, I don't want to use
normal variables (what's the correct
term for them by the way?)
There is no correct name for them, typically you can just say pointers for most discussions (except this one) and everything you need to discuss will also apply to references. You initialize non pointer, non reference members in the same way via the initailizer list.
class Foo
{
public:
Foo() : x(0), y(4)
{
}
int x, y;
};
Answer to Question 4:
pointers can be declared uninitialized
(by the way, is it best practice to
set this to NULL?).
They can be declared uninitialized yes. It is better to initialize them to NULL because then you can check if they are valid.
int *p = NULL;
//...
//Later in code
if(p)
{
//Do something with p
}
Answer to Question 5:
It looks like I have to use pointers
in this scenario, is this true? Also,
what's the best way of using the
variable?
You can use either pointers or references, but references cannot be re-assigned and references cannot be NULL. A pointer is just like any other variable, like an int, but it holds a memory address. An array is an aliased name for another variable.
A pointer has its own memory address, whereas an array should be seen as sharing the address of the variable it references.
With a reference, after it is initialized and declared, you use it just like you would have used the variable it references. There is no special syntax.
With a pointer, to access the value at the address it holds, you have to dereference the pointer. You do this by putting a * before it.
int x=0;
int *p = &x;//p holds the address of x
int &r(x);//r is a reference to x
//From this point *p == r == x
*p = 3;//change x to 3
r = 4;//change x to 4
//Up until now
int y=0;
p = &y;//p now holds the address of y instead.
Answer to Question 6:
What about smart pointers, etc? Is
this relevant?
Smart pointers (See boost::shared_ptr) are used so that when you allocate on the heap, you do not need to manually free your memory. None of the examples I gave above allocated on the heap. Here is an example where the use of smart pointers would have helped.
void createANewFooAndCallOneOfItsMethods(Bar &bar)
{
Foo *p = new Foo(bar);
p->f();
//The memory for p is never freed here, but if you would have used a smart pointer then it would have been freed here.
}
Answer to Question 7:
Update 1:
After attempting to implement a
reference variable field in my class
and initializing it in the
constructor, why might I receive the
following error?
The problem is that you didn't specify an initializer list. See my answer to question 2 above. Everything after the colon :
class VTexture
{
public:
VTexture(vimrid::imaging::ImageMatrix &rImage)
: image(rImage)
{
}
private:
vimrid::imaging::ImageMatrix ℑ
}
They can be initialized. You just have to use the member initializer list.
Foo::Foo(...) : bar1(...), bar2(...), bar3(...)
{
// Whatever
}
It's a good idea to initialize all of your member variables this way. Otherwise, for other than primitive types, C++ will initialize them with a default constructor anyway. Assigning them within the braces is actually reassigning them, not initializing them.
Also, keep in mind that the member initializer list specifies HOW to initialize the member variables, NOT THE ORDER. Members are initialized in the order in which they are declared, not in the order of the initializers.
Use the null object design pattern
I'm using ints but it would be the same with any type.
//header file
class Foo
{
public:
Foo( void );
Foo( int& i );
private:
int& m_int;
};
//source file
static int s_null_Foo_m_i;
Foo::Foo( void ) :
m_i(s_null_Foo_m_i)
{ }
Foo::Foo( int& i ) :
m_i(i)
{ }
Now you have to make sure that Foo makes sense when default constructed. You can even detect when Foo has been default constructed.
bool Foo::default_constructed( void )
{
return &m_i == &s_null_Foo_m_i;
}
I absolutely agree with the sentiment, Always prefer references over pointers. There are two notable cases where you can't get away with a reference member:
Null has a meaningful value.
This can be avoided with the null object design pattern.
The class has to be assignable.
The compiler will not generate an assignment operator for classes that have a reference member. You can define one yourself, but you will not be able to change where the reference is bound.
There is also a side effect when you define when you define Bar and Bar *
class Foo
{
public:
Bar bar1; // Here, you create a dependency on the definition of Bar, so the header //file for bar always needs to be included.
Bar &bar2;
Bar *bar3; //Here, you create a pointer, and a forward declaration is enough, you don't have to always include the header files for Bar , which is preferred.
}
Using references just because the -> syntax is cumbersome isn't the best reason... References have the one great advatage over pointers in that nulls aren't possible without casting trickery, but also disadvantages in initialization and the risk of accidentally illegaly binding temporaries which then go out of scope (for instance, after an implicit conversion).
Yes, smart pointers such as the boost ones are almost always the right answer for handling composite members, and occasionally for associated members (shared_ptr).
class Foo {
public:
Bar bar1;
Bar &bar2;
Bar *bar3;
// member bar2 must have an initializer in the constructor
Bar::Bar(Bar& _bar2) : bar1(), bar2(_bar2), bar3(new Bar()) {}
Bar::~Bar() {delete bar3;}
}
Note that bar2 isn't just initialized in the ctor; it's initialized with a bar object that's passed in as a reference parameter. That object and the bar2 field will be bound together for the life of the new Foo object. That is usually a very bad idea, because it's hard to ensure that the lifetimes of the two objects will be well coordinated (i.e., that you will never dispose of the passed-in bar object before disposing of the Foo object.)
This is why it's greatly preferred to use either instance variables (as in bar1) or pointers to objects allocated on the heap (as in bar3.)