Changing behavior of an object at runtime - c++

How can be changed the behavior of an object at runtime? (using C++)
I will give a simple example. I have a class Operator that contains a method operate. Let’s suppose it looks like this:
double operate(double a, double b){
return 0.0;
}
The user will give some input values for a and b, and will choose what operation to perform let’s say that he can choose to compute addition or multiplication. Given it’s input all I am allowed to do is instantiate Operator and call operate(a, b), which is written exactly how I mentioned before.
The methods that compute multiplication or addition will be implemented somewhere (no idea where).
In conclusion I have to change the behavior of my Operator object depending on the user's input.

The standard pattern for this is to make the outer class have a pointer to an "implementation" class.
// derive multiple implementations from this:
class Implementation
{
virtual ~Implementation() {} // probably essential!
virtual void foo() = 0;
};
class Switcheroo
{
Implementation *impl_;
public:
// constructor, destructor, copy constructor, assignment
// must all be properly defined (any that you can't define,
// make private)
void foo()
{
impl_->foo();
}
};
By forwarding all the member functions of Switcheroo to the impl_ member, you get the ability to switch in a different implementation whenever you need to.
There are various names for this pattern: Pimpl (short for "private implementation"), Smart Reference (as opposed to Smart Pointer, due to the fowarding member functions), and it has something in common with the Proxy and Bridge patterns.

I'm mentioning this only as trivia and can't unrecommend it more, but here we go...
WARNING DANGER!!!
A stupid trick I've seen is called clutching, I think, but it's only for the truely foolish. Basically you swap the virtualtable pointer to that of another class, it works, but it could theoretically destroy the world or cause some other undefined behavior :)
Anyways instead of this just use dynamic classing and kosher C++, but as an experiment the above is kind of fun...

Coplien's Envelope/Letter Pattern (in his must read book Advanced C++ Programming Styles and Idioms) is the classic way to do this.
Briefly, an Envelope and a Letter are both subclasses of an abstract base class/interfcae that defines the public interface for all subclasses.
An Envelope holds (and hides the true type of) a Letter.
A variety of Letter classes have different implementations of the abstract class's public interface.
An Envelope has no real implementation; it just forards (delegates) to its Letter. It holds a pointer to the abstract base class, and points that at a concrete Letter class instance. As the implementation needs to be changed, the type of Letter subclass pointer to is changed.
As users only have a reference to the Envelope, this change is invisible to them except in that the Envelope's behavior changes.
Coplien's examples are particularly clean, because it's the Letters, not the envelope that cause the change.
One example is of a Number class hierarchy. The abstract base declares certain operations over all Numbers, e.g, addition. Integer and a Complex are examples of concrete subclasses.
Adding an Integer and an Integer results in an Integer, but adding a Interget and a Complex results in a Complex.
Here's what the Envelope looks like for addition:
public class Number {
Number* add( const Number* const n ) ; // abstract, deriveds override
}
public class Envelope : public Number {
private Number* letter;
...
Number* add( const Number& rhs) { // add a number to this
// if letter and rhs are both Integers, letter->add returns an Integer
// if letter is a a Complex, or rhs is, what comes back is a Complex
//
letter = letter->add( rhs ) ) ;
return this;
}
}
Now in the client's pointer never changes, and they never ever need to know what the Envelop is holding. Here's the client code:
int main() {
// makeInteger news up the Envelope, and returns a pointer to it
Number* i = makeInteger( 1 ) ;
// makeComplex is similar, both return Envelopes.
Number* c = makeComplex( 1, 1 ) ;
// add c to i
i->add(c) ;
// to this code, i is now, for all intents and purposes, a Complex!
// even though i still points to the same Envelope, because
// the envelope internally points to a Complex.
}
In his book, Coplien goes into greater depth -- you'll note that the add method requires multi-dispatch of some form --, and adds syntactic sugar. But this is the gist of how you can get what's called "runtime polymorphism".

You can achieve it through dynamic binding (polymorphism)... but it all depends on what you are actually trying to achieve.

You can't change the behavior of arbitrary objects using any sane way unless the object was intended to use 'plugin' behaviour through some technique (composition, callbacks etc).
(Insane ways might be overwriting process memory where the function code lies...)
However, you can overwrite an object's behavior that lies in virtual methods by overwriting the vtable (An approach can be found in this article ) without overwriting memory in executable pages. But this still is not a very sane way to do it and it bears multiple security risks.
The safest thing to do is to change the behavior of objects that were designed to be changed by providing the appropriate hooks (callbacks, composition ...).

Objects always have the behaviour that's defined by their class.
If you need different behaviour, you need a different class...

You could also consider the Role Pattern with dynamic binding..i'm struggling with the same thing that you do..I read about the Strategy pattern but the role one sounds like a good solution also...

There are many ways to do this proxying, pImpl idiom, polymorphism, all with pros and cons. The solution that is best for you will depend on exactly which problem you are trying to solve.

Many many ways:
Try if at first. You can always change the behavior with if statement. Then you probably find the 'polymorphism' way more accurate, but it depends on your task.

Create a abstract class, declaring the methods, which behavior must be variable, as virtual.
Create concrete classes, that will implement the virtual methods. There are many ways to achieve this, using design patterns.

You can change the object behavior using dynamic binding. The design patterns like Decorator, Strategy would actually help you to realize the same.

Related

Vector of pointers to base type, find all instances of a given derived type stored in a base type

Suppose you have a base class inside of a library:
class A {};
and derived classes
class B: public A {};
class C: public A {};
Now Instances of B and C are stored in a std::vector of boost::shared_ptr<A>:
std::vector<boost::shared_ptr<A> > A_vec;
A_vec.push_back(boost::shared_ptr<B>(new B()));
A_vec.push_back(boost::shared_ptr<C>(new C()));
Adding instances of B and C is done by a user, and there is no way to determine in advance the order, in which they will be added.
However, inside of the library, there may be a need to perform specific actions on B and C, so the pointer to the base class needs to be casted to B and C.
I can of course do "trial and error" conversions, i.e. try to cast to Band C(and any other derivative of the base class), until I find a conversion that doesn't throw. However, this method seems very crude and error-prone, and I'm looking for a more elegant (and better performing) way.
I am looking for a solution that will also work with C++98, but may involve boost functionality.
Any ideas ?
EDIT:
O.k., thanks for all the answers so far!
I'd like to give some more details regarding the use-case. All of this happens in the context of parametric optimization.
Users define the optimization problem by:
Specifying the parameters, i.e. their types (e.g. "constrained double", "constrained integer", "unconstrained double", "boolean", etc.) and initial values
Specifying the evaluation function, which assigns one or more evaluations (double values) to a given parameter set
Different optimization algorithms then act on the problem definitions, including their parameters.
There is a number of predefined parameter objects for common cases, but users may also create their own parameter objects, by deriving from one of my base classes. So from a library perspective, apart from the fact that the parameter objects need to comply with a given (base-class) API, I cannot assume much about parameter objects.
The problem definition is a user-defined C++-class, derived from a base-class with a std::vector interface. The user adds his (predefined or home-grown) parameter objects and overloads a fitness-function.
Access to the parameter objects may happen
from within the optimization algorithms (usually o.k., even for home-grown parameter objects, as derived parameter objects need to provide access functions for their values).
from within the user-supplied fitness function (usually o.k., as the user knows where to find which parameter object in the collection and its value can be accessed easily)
This works fine.
There may however be special cases where
a user wants to access specifics of his home-grown parameter types
a third party has supplied the parameter structure (this is an Open Source library, others may add code for specific optimization problems)
the parameter structure (i.e. which parameters are where in the vector) may be modified as part of the optimization problem --> example: training of the architecture of a neural network
Under these circumstances it would be great to have an easy method to access all parameter objects of a given derived type inside of the collection of base types.
I already have a templated "conversion_iterator". It iterates over the vector of base objects and skips those that do not comply with the desired target type. However, this is based on "trial and error" conversion (i.e. I check whether the converted smart pointer is NULL), which I find very unelegant and error-prone.
I'd love to have a better solution.
NB: The optimization library is targetted at use-cases, where the evaluation step for a given parameter set may last arbitrarily long (usually seconds, possibly hours or longer). So speed of access to parameter types is not much of an issue. But stability and maintainability is ...
There’s no better general solution than trying to cast and seeing whether it succeeds. You can alternatively derive the dynamic typeid and compare it to all types in turn, but that is effectively the same amount of work.
More fundamentally, your need to do this hints at a design problem: the whole purpose of a base class is to be able to treat children as if they were parents. There are certain situations where this is necessary though, in which case you’d use a visitor to dispatch them.
If possible, add virtual methods to class A to do the "specific actions on B and C".
If that's not possible or not reasonable, use the pointer form of dynamic_cast, so there are no exceptions involved.
for (boost::shared_ptr<A> a : A_vec)
{
if (B* b = dynamic_cast<B*>(a.get()))
{
b->do_something();
}
else if (C* c = dynamic_cast<C*>(a.get()))
{
something_else(*c);
}
}
Adding instances of B and C is done by a user, and there is no way to determine in advance the order, in which they will be added.
Okay, so just put them in two different containers?
std::vector<boost::shared_ptr<A> > A_vec;
std::vector<boost::shared_ptr<B> > B_vec;
std::vector<boost::shared_ptr<C> > C_vec;
void add(B * p)
{
B_vec.push_back(boost::shared_ptr<B>(p));
A_vec.push_back(b.back());
}
void add(C * p)
{
C_vec.push_back(boost::shared_ptr<C>(p));
A_vec.push_back(c.back());
}
Then you can iterate over the Bs or Cs to your hearts content.
I would suggest to implement a method in the base class (e.g. TypeOf()), which will return the type of the particular object. Make sure you define that method as virtual and abstract so that you will be enforced to implement in the derived types. As for the type itself, you can define an enum for each type (e.g. class).
enum class ClassType { ClassA, ClassB, ClassC };
This answer might interest you: Generating an interface without virtual functions?
This shows you both approaches
variant w/visitor in a single collection
separate collections,
as have been suggested by others (Fred and Konrad, notably). The latter is more efficient for iteration, the former could well be more pure and maintainable. It could even be more efficient too, depending on the usage patterns.

Why bother with virtual functions in c++?

This is not a question about how they work and declared, this I think is pretty much clear to me. The question is about why to implement this?
I suppose the practical reason is to simplify bunch of other code to relate and declare their variables of base type, to handle objects and their specific methods from many other subclasses?
Could this be done by templating and typechecking, like I do it in Objective C? If so, what is more efficient? I find it confusing to declare object as one class and instantiate it as another, even if it is its child.
SOrry for stupid questions, but I havent done any real projects in C++ yet and since I am active Objective C developer (it is much smaller language thus relying heavily on SDK's functionalities, like OSX, iOS) I need to have clear view on any parallel ways of both cousins.
Yes, this can be done with templates, but then the caller must know what the actual type of the object is (the concrete class) and this increases coupling.
With virtual functions the caller doesn't need to know the actual class - it operates through a pointer to a base class, so you can compile the client once and the implementor can change the actual implementation as much as it wants and the client doesn't have to know about that as long as the interface is unchanged.
Virtual functions implement polymorphism. I don't know Obj-C, so I cannot compare both, but the motivating use case is that you can use derived objects in place of base objects and the code will work. If you have a compiled and working function foo that operates on a reference to base you need not modify it to have it work with an instance of derived.
You could do that (assuming that you had runtime type information) by obtaining the real type of the argument and then dispatching directly to the appropriate function with a switch of shorts, but that would require either manually modifying the switch for each new type (high maintenance cost) or having reflection (unavailable in C++) to obtain the method pointer. Even then, after obtaining a method pointer you would have to call it, which is as expensive as the virtual call.
As to the cost associated to a virtual call, basically (in all implementations with a virtual method table) a call to a virtual function foo applied on object o: o.foo() is translated to o.vptr[ 3 ](), where 3 is the position of foo in the virtual table, and that is a compile time constant. This basically is a double indirection:
From the object o obtain the pointer to the vtable, index that table to obtain the pointer to the function and then call. The extra cost compared with a direct non-polymorphic call is just the table lookup. (In fact there can be other hidden costs when using multiple inheritance, as the implicit this pointer might have to be shifted), but the cost of the virtual dispatch is very small.
I don't know the first thing about Objective-C, but here's why you want to "declare an object as one class and instantiate it as another": the Liskov Substitution Principle.
Since a PDF is a document, and an OpenOffice.org document is a document, and a Word Document is a document, it's quite natural to write
Document *d;
if (ends_with(filename, ".pdf"))
d = new PdfDocument(filename);
else if (ends_with(filename, ".doc"))
d = new WordDocument(filename);
else
// you get the point
d->print();
Now, for this to work, print would have to be virtual, or be implemented using virtual functions, or be implemented using a crude hack that reinvents the virtual wheel. The program need to know at runtime which of various print methods to apply.
Templating solves a different problem, where you determine at compile time which of the various containers you're going to use (for example) when you want to store a bunch of elements. If you operate on those containers with template functions, then you don't need to rewrite them when you switch containers, or add another container to your program.
A virtual function is important in inheritance. Think of an example where you have a CMonster class and then a CRaidBoss and CBoss class that inherit from CMonster.
Both need to be drawn. A CMonster has a Draw() function, but the way a CRaidBoss and a CBoss are drawn is different. Thus, the implementation is left to them by utilizing the virtual function Draw.
Well, the idea is simply to allow the compiler to perform checks for you.
It's like a lot of features : ways to hide what you don't want to have to do yourself. That's abstraction.
Inheritance, interfaces, etc. allow you to provide an interface to the compiler for the implementation code to match.
If you didn't have the virtual function mecanism, you would have to write :
class A
{
void do_something();
};
class B : public A
{
void do_something(); // this one "hide" the A::do_something(), it replace it.
};
void DoSomething( A* object )
{
// calling object->do_something will ALWAYS call A::do_something()
// that's not what you want if object is B...
// so we have to check manually:
B* b_object = dynamic_cast<B*>( object );
if( b_object != NULL ) // ok it's a b object, call B::do_something();
{
b_object->do_something()
}
else
{
object->do_something(); // that's a A, call A::do_something();
}
}
Here there are several problems :
you have to write this for each function redefined in a class hierarchy.
you have one additional if for each child class.
you have to touch this function again each time you add a definition to the whole hierarcy.
it's visible code, you can get it wrong easily, each time
So, marking functions virtual does this correctly in an implicit way, rerouting automatically, in a dynamic way, the function call to the correct implementation, depending on the final type of the object.
You dont' have to write any logic so you can't get errors in this code and have an additional thing to worry about.
It's the kind of thing you don't want to bother with as it can be done by the compiler/runtime.
The use of templates is also technically known as polymorphism from theorists. Yep, both are valid approach to the problem. The implementation technics employed will explain better or worse performance for them.
For example, Java implements templates, but through template erasure. This means that it is only apparently using templates, under the surface is plain old polymorphism.
C++ has very powerful templates. The use of templates makes code quicker, though each use of a template instantiates it for the given type. This means that, if you use an std::vector for ints, doubles and strings, you'll have three different vector classes: this means that the size of the executable will suffer.

runtime type comparison

I need to find the type of object pointed by pointer.
Code is as below.
//pWindow is pointer to either base Window object or derived Window objects like //Window_Derived.
const char* windowName = typeid(*pWindow).name();
if(strcmp(windowName, typeid(Window).name()) == 0)
{
// ...
}
else if(strcmp(windowName, typeid(Window_Derived).name()) == 0)
{
// ...
}
As i can't use switch statement for comparing string, i am forced to use if else chain.
But as the number of window types i have is high, this if else chain is becoming too lengthy.
Can we check the window type using switch or an easier method ?
EDIT: Am working in a logger module. I thought, logger should not call derived class virtual function for logging purpose. It should do on its own. So i dropped virtual function approach.
First of all use a higher level construct for strings like std::string.
Second, if you need to check the type of the window your design is wrong.
Use the Liskov substitution principle to design correctly.
It basically means that any of the derived Window objects can be replaced with it's super class.
This can only happen if both share the same interface and the derived classes don't violate the contract provided by the base class.
If you need some mechanism to apply behavior dynamically use the Visitor Pattern
Here are the things to do in order of preference:
Add a new virtual method to the base class and simply call it. Then put a virtual method of the same name in each derived class that implements the corresponding else if clause inside it. This is the preferred option as your current strategy is a widely recognized symptom of poor design, and this is the suggested remedy.
Use a ::std::map< ::std::string, void (*)(Window *pWindow)>. This will allow you to look up the function to call in a map, which is much faster and easier to add to. This will also require you to split each else if clause into its own function.
Use a ::std::map< ::std::string, int>. This will let you look up an integer for the corresponding string and then you can switch on the integer.
There are other refactoring strategies to use that more closely resemble option 1 here. For example,if you can't add a method to the Window class, you can create an interface class that has the needed method. Then you can make a function that uses dynamic_cast to figure out if the object implements the interface class and call the method in that case, and then handle the few remaining cases with your else if construct.
Create a dictionary (set/hashmap) with the strings as keys and the behaviour as value.
Using behaviour as values can be done in two ways:
Encapsulate each behaviour in it's
own class that inherit from an
interface with"DoAction" method that
execute the behavior
Use function pointers
Update:
I found this article that might be what you're looking for:
http://www.dreamincode.net/forums/topic/38412-the-command-pattern-c/
You might try putting all your typeid(...).name() values in a map, then doing a find() in the map. You could map to an int that can be used in a switch statement, or to a function pointer. Better yet, you might look again at getting a virtual function inside each of the types that does what you need.
What you ask for is possible, it's also unlikely to be a good solution to your problem.
Effectively the if/else if/else chain is ugly, the first solution that comes to mind will therefore to use a construct that will lift this, an associative container comes to mind and the default one is obviously std::unordered_map.
Thinking on the type of this container, you will realize that you need to use the typename as the key and associate it to a functor object...
However there are much more elegant constructs for this. The first of all will be of course the use of a virtual method.
class Base
{
public:
void execute() const { this->executeImpl(); }
private:
virtual void executeImpl() const { /* default impl */ }
};
class Derived: public Base
{
virtual void executeImpl() const { /* another impl */ }
};
It's the OO way of dealing with this type of requirement.
Finally, if you find yourself willing to add many different operations on your hierarchy, I will suggest the use of a well-known design pattern: Visitor. There is a variation called Acyclic Visitor which helps dealing with dependencies.

C++ checking the type of reference

Is it bad design to check if an object is of a particular type by having some sort of ID data member in it?
class A
{
private:
bool isStub;
public:
A(bool isStubVal):isStub(isStubVal){}
bool isStub(){return isStub;}
};
class A1:public A
{
public:
A1():A(false){}
};
class AStub:public A
{
public:
AStub():A(true){}
};
EDIT 1:
Problem is A holds a lot of virtual functions, which A1 doesn't override but the stub needs to, for indidicating that you are working on a stub instead of an actual object. Here maintainability is the question, for every function that i add to A, i need to override it in stub. forgetting it means dangerous behaviour as A's virtual function gets executed with stub's data. Sure I can add an abstract class ABase and let A and Astub inherit from them. But the design has become rigid enough to allow this refactor.
A reference holder to A is held in another class B. B is initialized with the stub reference, but later depending on some conditions, the reference holder in B is reinitialized with the A1,A2 etc.. So when i do this BObj.GetA(), i can check in GetA() if the refholder is holding a stub and then give an error in that case. Not doing that check means, i would have to override all functions of A in AStub with the appropriate error conditions.
Generally, yes. You're half OO, half procedural.
What are you going to do once you determine the object type? You probably should put that behavior in the object itself (perhaps in a virtual function), and have different derived classes implement that behavior differently. Then you have no reason to check the object type at all.
In your specific example you have a "stub" class. Instead of doing...
if(!stub)
{
dosomething;
}
Just call
object->DoSomething();
and have the implemention in AStub be a empty
Generally yes. Usually you want not to query the object, but to expect it to BEHAVE the proper way. What you suggest is basically a primitive RTTI, and this is generally frowned upon, unless there are better options.
The OO way would be to Stub the functionality, not check for it. However, in the case of a lot of functions to "stub" this may not seem optimal.
Hence, this depends on what you want the class to really do.
Also note, that in this case you don't waste space:
class A
{
public:
virtual bool isStub() = 0;
};
class A1:public A
{
public:
virtual bool isStub() { return false; };
};
class AStub:public A
{
public:
virtual bool isStub() { return true; };
};
... buuut you have a virtual function -- what usually is not a problem, unless it's a performance bottleneck.
If you want to find out the type of object at runtime you can use a dynamic_cast. You must have a pointer or reference to the object, and then check the result of the dynamic_cast. If it is not NULL, then the object is the correct type.
With polymorphic classes you can use the typeofoperator to perform RTTI. Most of the time you shouldn't need to. Without polymorphism, there's no language facility to do so, but you should need to even less often.
One caveat. Obviously your type is going to be determined at construction time. If your determination of 'type' is a dynamic quantity you can't solve this problem with the C++ type system. In that case you need to have some function. But in this case it is better to use the overridable/dynamic behavior as Terry suggested.
Can you provide some better information as what you are trying to accomplish?
This sort of thing is fine. It's generally better to put functionality in the object, so that there's no need to switch on type -- this makes the calling code simpler and localises future changes -- but there's a lot to be said for being able to check the types.
There will always be exceptions to the general case, even with the best will in the world, and being able to quickly check for the odd specific case can make the difference between having something fixed by one change in one place, a quick project-specific hack in the project-specific code, and having to make more invasive, wide-reaching changes (extra functions in the base class at the very least) -- possibly pushing project-specific concerns into shared or framework code.
For a quick solution to the problem, use dynamic_cast. As others have noted, this lets one check that an object is of a given type -- or a type derived from that (an improvement over the straightforward "check IDs" approach). For example:
bool IsStub( const A &a ) {
return bool( dynamic_cast< const AStub * >( &a ) );
}
This requires no setup, and without any effort on one's part the results will be correct. It is also template-friendly in a very straightforward and obvious manner.
Two other approaches may also suit.
If the set of derived types is fixed, or there are a set of derived types that get commonly used, one might have some functions on the base class that will perform the cast. The base class implementations return NULL:
class A {
virtual AStub *AsStub() { return NULL; }
virtual OtherDerivedClass *AsOtherDerivedClass() { return NULL; }
};
Then override as appropriate, for example:
class AStub : public A {
AStub *AsStub() { return this; }
};
Again, this allows one to have objects of a derived type treated as if they were their base type -- or not, if that would be preferable. A further advantage of this is that one need not necessarily return this, but could return a pointer to some other object (a member variable perhaps). This allows a given derived class to provide multiple views of itself, or perhaps change its role at runtime.
This approach is not especially template friendly, though. It would require a bit of work, with the result either being a bit more verbose or using constructs with which not everybody is familiar.
Another approach is to reify the object type. Have an actual object that represents the type, that can be retrieved by both a virtual function and a static function. For simple type checking, this is not much better than dynamic_cast, but the cost is more predictable across a wide range of compilers, and the opportunities for storing useful data (proper class name, reflection information, navigable class hierarchy information, etc.) are much greater.
This requires a bit of infrastructure (a couple of macros, at least) to make it easy to add the virtual functions and maintain the hierarchy data, but it provides good results. Even if this is only used to store class names that are guaranteed to be useful, and to check for types, it'll pay for itself.
With all this in place, checking for a particular type of object might then go something like this example:
bool IsStub( const A &a ) {
return a.GetObjectType().IsDerivedFrom( AStub::GetClassType() );
}
(IsDerivedFrom might be table-driven, or it could simply loop through the hierarchy data. Either of these may or may not be more efficient than dynamic_cast, but the approximate runtime cost is at least predictable.)
As with dynamic_cast, this approach is also obviously amenable to automation with templates.
In the general case it might not be a good design, but in some specific cases it is a reasonable design choice to provide an isStub() method for the use of a specific client that would otherwise need to use RTTI. One such case is lazy loading:
class LoadingProxy : IInterface
{
private:
IInterface m_delegate;
IInterface loadDelegate();
public:
LoadingProxy(IInterface delegate) : m_delegate(delegate){}
int useMe()
{
if (m_delegate.isStub())
{
m_delegate = loadDelegate();
}
return m_delegate.useMe();
}
};
The problem with RTTI is that it is relatively expensive (slow) compared with a virtual method call, so that if your useMe() function is simple/quick, RTTI determines the performance. On one application that I worked on, using RTTI tests to determine if lazy loading was needed was one of the performance bottlenecks identified by profiling.
However, as many other answers have said, the application code should not need to worry about whether it has a stub or a usable instance. The test should be in one place/layer in the application. Unless you might need multiple LoadingProxy implementations there might be a case for making isStub() a friend function.

C++: Copy constructor: Use getters or access member vars directly?

I have a simple container class with a copy constructor.
Do you recommend using getters and setters, or accessing the member variables directly?
public Container
{
public:
Container() {}
Container(const Container& cont) //option 1
{
SetMyString(cont.GetMyString());
}
//OR
Container(const Container& cont) //option 2
{
m_str1 = cont.m_str1;
}
public string GetMyString() { return m_str1;}
public void SetMyString(string str) { m_str1 = str;}
private:
string m_str1;
}
In the example, all code is inline, but in our real code there is no inline code.
Update (29 Sept 09):
Some of these answers are well written however they seem to get missing the point of this question:
this is simple contrived example to discuss using getters/setters vs variables
initializer lists or private validator functions are not really part of this question. I'm wondering if either design will make the code easier to maintain and expand.
Some ppl are focusing on the string in this example however it is just an example, imagine it is a different object instead.
I'm not concerned about performance. we're not programming on the PDP-11
EDIT: Answering the edited question :)
this is simple contrived example to
discuss using getters/setters vs
variables
If you have a simple collection of variables, that don't need any kind of validation, nor additional processing then you might consider using a POD instead. From Stroustrup's FAQ:
A well-designed class presents a clean
and simple interface to its users,
hiding its representation and saving
its users from having to know about
that representation. If the
representation shouldn't be hidden -
say, because users should be able to
change any data member any way they
like - you can think of that class as
"just a plain old data structure"
In short, this is not JAVA. you shouldn't write plain getters/setters because they are as bad as exposing the variables them selves.
initializer lists or private validator functions are not really
part of this question. I'm wondering
if either design will make the code
easier to maintain and expand.
If you are copying another object's variables, then the source object should be in a valid state. How did the ill formed source object got constructed in the first place?! Shouldn't constructors do the job of validation? aren't the modifying member functions responsible of maintaining the class invariant by validating input? Why would you validate a "valid" object in a copy constructor?
I'm not concerned about performance. we're not programming on the PDP-11
This is about the most elegant style, though in C++ the most elegant code has the best performance characteristics usually.
You should use an initializer list. In your code, m_str1 is default constructed then assigned a new value. Your code could be something like this:
class Container
{
public:
Container() {}
Container(const Container& cont) : m_str1(cont.m_str1)
{ }
string GetMyString() { return m_str1;}
void SetMyString(string str) { m_str1 = str;}
private:
string m_str1;
};
#cbrulak You shouldn't IMO validate cont.m_str1 in the copy constructor. What I do, is to validate things in constructors. Validation in copy constructor means you you are copying an ill formed object in the first place, for example:
Container(const string& str) : m_str1(str)
{
if(!valid(m_str1)) // valid() is a function to check your input
{
// throw an exception!
}
}
You should use an initializer list, and then the question becomes meaningless, as in:
Container(const Container& rhs)
: m_str1(rhs.m_str1)
{}
There's a great section in Matthew Wilson's Imperfect C++ that explains all about Member Initializer Lists, and about how you can use them in combination with const and/or references to make your code safer.
Edit: an example showing validation and const:
class Container
{
public:
Container(const string& str)
: m_str1(validate_string(str))
{}
private:
static const string& validate_string(const string& str)
{
if(str.empty())
{
throw runtime_error("invalid argument");
}
return str;
}
private:
const string m_str1;
};
As it's written right now (with no qualification of the input or output) your getter and setter (accessor and mutator, if you prefer) are accomplishing absolutely nothing, so you might as well just make the string public and be done with it.
If the real code really does qualify the string, then chances are pretty good that what you're dealing with isn't properly a string at all -- instead, it's just something that looks a lot like a string. What you're really doing in this case is abusing the type system, sort of exposing a string, when the real type is only something a bit like a string. You're then providing the setter to try to enforce whatever restrictions the real type has compared to a real string.
When you look at it from that direction, the answer becomes fairly obvious: rather than a string, with a setter to make the string act like some other (more restricted) type, what you should be doing instead is defining an actual class for the type you really want. Having defined that class correctly, you make an instance of it public. If (as seems to be the case here) it's reasonable to assign it a value that starts out as a string, then that class should contain an assignment operator that takes a string as an argument. If (as also seems to be the case here) it's reasonable to convert that type to a string under some circumstances, it can also include cast operator that produces a string as the result.
This gives a real improvement over using a setter and getter in a surrounding class. First and foremost, when you put those in a surrounding class, it's easy for code inside that class to bypass the getter/setter, losing enforcement of whatever the setter was supposed to enforce. Second, it maintains a normal-looking notation. Using a getter and a setter forces you to write code that's just plain ugly and hard to read.
One of the major strengths of a string class in C++ is using operator overloading so you can replace something like:
strcpy(strcat(filename, ".ext"));
with:
filename += ".ext";
to improve readability. But look what happens if that string is part of a class that forces us to go through a getter and setter:
some_object.setfilename(some_object.getfilename()+".ext");
If anything, the C code is actually more readable than this mess. On the other hand, consider what happens if we do the job right, with a public object of a class that defines an operator string and operator=:
some_object.filename += ".ext";
Nice, simple and readable, just like it should be. Better still, if we need to enforce something about the string, we can inspect only that small class, we really only have to look one or two specific, well-known places (operator=, possibly a ctor or two for that class) to know that it's always enforced -- a totally different story from when we're using a setter to try to do the job.
Do you anticipate how the string is returned, eg. white space trimmed, null checked, etc.? Same with SetMyString(), if the answer is yes, you are better off with access methods since you don't have to change your code in zillion places but just modify those getter and setter methods.
Ask yourself what the costs and benefits are.
Cost: higher runtime overhead. Calling virtual functions in ctors is a bad idea, but setters and getters are unlikely to be virtual.
Benefits: if the setter/getter does something complicated, you're not repeating code; if it does something unintuitive, you're not forgetting to do that.
The cost/benefit ratio will differ for different classes. Once you're ascertained that ratio, use your judgment. For immutable classes, of course, you don't have setters, and you don't need getters (as const members and references can be public as no one can change/reseat them).
There's no silver bullet as how to write the copy constructor.
If your class only has members which provide a copy constructor that creates
instances which do not share state (or at least do not appear to do so) using an initializer list is a good way.
Otherwise you'll have to actually think.
struct alpha {
beta* m_beta;
alpha() : m_beta(new beta()) {}
~alpha() { delete m_beta; }
alpha(const alpha& a) {
// need to copy? or do you have a shared state? copy on write?
m_beta = new beta(*a.m_beta);
// wrong
m_beta = a.m_beta;
}
Note that you can get around the potential segfault by using smart_ptr - but you can have a lot of fun debugging the resulting bugs.
Of course it can get even funnier.
Members which are created on demand.
new beta(a.beta) is wrong in case you somehow introduce polymorphism.
... a screw the otherwise - please always think when writing a copy constructor.
Why do you need getters and setters at all?
Simple :) - They preserve invariants - i.e. guarantees your class makes, such as "MyString always has an even number of characters".
If implemented as intended, your object is always in a valid state - so a memberwise copy can very well copy the members directly without fear of breaking any guarantee. There is no advantage of passing already validated state through another round of state validation.
As AraK said, the best would be using an initializer list.
Not so simple (1):
Another reason to use getters/setters is not relying on implementation details. That's a strange idea for a copy CTor, when changing such implementation details you almost always need to adjust CDA anyway.
Not so simple (2):
To prove me wrong, you can construct invariants that are dependent on the instance itself, or another external factor. One (very contrieved) example: "if the number of instances is even, the string length is even, otherwise it's odd." In that case, the copy CTor would have to throw, or adjust the string. In such a case it might help to use setters/getters - but that's not the general cas. You shouldn't derive general rules from oddities.
I prefer using an interface for outer classes to access the data, in case you want to change the way it's retrieved. However, when you're within the scope of the class and want to replicate the internal state of the copied value, I'd go with data members directly.
Not to mention that you'll probably save a few function calls if the getter are not inlined.
If your getters are (inline and) not virtual, there's no pluses nor minuses in using them wrt direct member access -- it just looks goofy to me in terms of style, but, no big deal either way.
If your getters are virtual, then there is overhead... but nevertheless that's exactly when you DO want to call them, just in case they're overridden in a subclass!-)
There is a simple test that works for many design questions, this one included: add side-effects and see what breaks.
Suppose setter not only assigns a value, but also writes audit record, logs a message or raises an event. Do you want this happen for every property when copying object? Probably not - so calling setters in constructor is logically wrong (even if setters are in fact just assignments).
Although I agree with other posters that there are many entry-level C++ "no-no's" in your sample, putting that to the side and answering your question directly:
In practice, I tend to make many but not all of my member fields* public to start with, and then move them to get/set when needed.
Now, I will be the first to say that this is not necessarily a recommended practice, and many practitioners will abhor this and say that every field should have setters/getters.
Maybe. But I find that in practice this isn't always necessary. Granted, it causes pain later when I change a field from public to a getter, and sometimes when I know what usage a class will have, I give it set/get and make the field protected or private from the start.
YMMV
RF
you call fields "variables" - I encourage you to use that term only for local variables within a function/method