In my company, we generate code from XML. The code generator generates header files that contain Messages, and each message contains only data. NOTE we don't do any validation while setting or returning data; also, we don't have to take care of the state, i.e., data x and data in a message are independent; if x is changed, we don't need to change the state of y.
Current header file
class somemessage
{
private:
Field _field;
.......
public:
Field& getfield(){...}
const Field& getfield() const {...}
void setfield(const Field& field){....}
} ;
Do we still need data hiding here if it's only data? Do we require getter and setters in these headers, or can se make it simple as following.
struct somemessage
{
Field field;
};
We can make the message read-only when required using const as following.
void message_consumer(const somemessage& message)
{
message.field = somevalue; // compilation error
}
What are the disadvantages of this approach, and what are the advantages of using accessors and mutators?
If you have the following pattern:
class A {
public:
void SetFoo(const Foo& newFoo) {
f = newFoo;
}
const Foo& GetFoo() const {
return f;
}
protected:
private:
Foo f;
};
That is, you have a getter/setter pair and all they do is have a single return statement and a single assignment expression, then there's no need for the data member to be private and instead just make the data member public and remove the getter/setter pair.
class A {
public:
Foo f;
protected:
private:
};
If your getters/setters do anything else, or are in any way more complicated, then yes, having a getter/setter pair is fine.
In terms of using a struct versus a class, I go with struct if the type is strictly only data; no functions, no constructors. If for whatever reason the data type needs functions, then it should be declared as a class.
Writing a getter like this:
Field& getfield(){...}
is not encapsulation. A user can do this:
Field& decapsulated = x.getField();
and now they have a reference to the private member that they can use to do what they like. All checking and bookkeeping in the setter is futile, because the user does not need it to modify the private member:
decapsulated = some_other_field;
Proper encapsulation has advantages. Though plain old structs with only public members have their place as well. If however all you do is writing boilerplate that does not encapsulate the data, you can leave away the boilerplate. Eventually it is up to you to decide what to use. Encapsulation has lots of advantages, but it is not a must.
Getters returning non-const references can be useful as convenience methods. They can provide easy means for the user to access the class data. Compare for example to std::vector::operator[] or std::vector::at(). Though one should not confuse that with data encapsulation.
Is it good to use a const reference field as a readonly getter in C++ classes?
I mean, does this code meet good practices?
class check{
private:
int _x;
public:
const int& x = _x;
void setX(int v){
_x = v;
}
};
It is working very much like C# properties, IMHO, and very easy and clean in class usage code:
check s;
int i;
std::cin >> i;
s.setX(i);
std::cout << s.x << '\n';
s.setX(7);
// s.x = i; // Error
std::cout<<s.x<<'\n';
do this code meet good practices?
Not really, since it introduces unnecessary complexity and space overhead.
Moreover, you wouldn't be able to perform runtime checks and/or assertions, regardless of the value being accessed.
Furthermore, what happens with the lifetime and semantics?
Try assigning one check in your code to another and see what happens. The assignment is ill-formed because the class is non-assignable. You should provide a copy and move constructor to take care of the reference, so that it won't refer to the old object's data member.
Better use _x directly and have a straightforward inline getter function.
PS: C#-like properties in native C++?
Generally, it is not a good practice.
imho, and very easy and clean in class usage code.
Why should that be clearer and easier?
You introduce another variable member (useless overhead). (Generally, the reference will be implemented as an additional member pointer).
It makes the code harder to maintain. You are actually creating dependencies among variable members.
It makes problem in the assignment and in the copy operations. How is copy operation supposed to work?
The "classic" approach is sound clearer by me, e.g.:
class Foo {
public:
void set_num(int value) noexcept { m_num = value; }
int get_num() const noexcept { return m_num; }
void set_string(std::string value) noexcept {
m_str = std::move(value);
}
const std::string& get_string() const noexcept {
return m_str;
}
private:
int m_num;
std::string m_str;
};
From a performances point of view, this approach should be preferred.
Timing complexity: call get_variable on an inline function does not introduce more overhead than your "reference approach". Moreover, it is highly optimizable by the compiler (because of straightforward of the code).
Space complexity: it does not introduce additional data member.
What you propose is in general a bad idea:
You can't implement the property by doing any processing (e.g. with a getter you can store co-ordinates using [x,y] and later decide to change the implementation to use [angle,radius] while keeping the same public interface).
Using a const member variable involves space overhead, and doesn't give you any performance advantage compared with an inline getter.
It's not idiomatic.
Once you've published your class, and other people start using it, you're stuck with it: it's too late to change it to use a method instead.
If your intention with properties is to make the code more succinct, you don't have to use the words "get" and "set" in your function names; that's an old-fashioned practice. You can use the actual name of the "property" as the function name, and you can overload the getter and setter:
class Cheque {
public:
int x() const {
return x_;
}
Cheque & x(int newX) {
x_ = newX;
return *this;
}
private:
int x_;
}
// Usage:
// int amt = myCheque.x(1234);
// Cheque c = Cheque().x(123);
Returning *this as in the above code enables you to use method chaining; a way of implementing the Fluent interface idiom.
When C# compiles a propery it gets compiled into a getter and a setter function.
Here's some C# code that proves this fact:
using System;
namespace Reflect
{
class Program
{
class X
{
public int Prop { get; set; }
}
static void Main(string[] args)
{
var type = typeof(X);
foreach (var method in type.GetMethods())
{
Console.WriteLine(method.Name);
}
Console.ReadKey();
}
}
}
Your output should be:
get_Prop
set_Prop
ToString
Equals
GetHashCode
GetType
get_Prop is the function that implements the getter.
set_Prop is the function that implements the setter.
So even if what you're doing looks similar, it's not the same at all.
Frankly almost everything you could do to try to emulate 'property syntax' in C++ will fall down in one way or another. Most solutions will either cost you memory or it'll have some limitation that makes it more cumbersome than useful.
Just learn to live with getters and setters.
Getters and setters are good practice.
They're short, they're simple, they're flexible, they're typically good candidates for inlining, everyone understands what they do et cetera.
How to make an adapter class to support both const and non-const underlying data appropriately?
Concrete Example
RigidBody is a class describing physic property of object.
Here is its very simplified version (1D):-
class RigidBody{
float position=1;
public: float getPosition()const{ return position;}
public: void setPosition(float ppos){ position=ppos;}
};
Adapter encapsulates RigidBody.
It provides a-little-distorted functionality to get/set position:-
class Adapter{
public: RigidBody* rigid; int offset=2;
public: float getPosition(){
return rigid->getPosition()+offset; //distort
}
public: void setPosition(float ppos){
return rigid->setPosition(ppos-offset); //distort
}
};
I can set position of RigidBody indirectly by using Adapter :-
int main() {
RigidBody rigid;
Adapter adapter; //Edit: In real life, this type is a parameter of many function
adapter.rigid=&rigid;
adapter.setPosition(5);
std::cout<<adapter.getPosition();//print 5
return 0;
}
Everything works (demo).
Objective
I want create a new function that receives constRigidBody* rigid.
I should be able to read from it (e.g. getPosition()) by using adapter.
However, I don't really know how to do it elegantly.
void test(const RigidBody* rigid){
Adapter adapter2;
//adapter2.rigid=rigid; //not work, how to make it work?
//adapter2.setPosition(5); //should not work
//adapter2.getPosition(); //should work
}
My poor solutions
Solution A1 (2 adapters + 1 widget)
Create a widget :-
class AdapterWidget{
public: static Adapter createAdapter(RigidBody* a);
public: static AdapterConst createAdapter(const RigidBody* a);
};
AdapterConst can only getPosition(), while AdapterConst can both get and set.
I can use it like :-
void test(const RigidBody* rigid){
auto adapter=AdapterWidget::createAdapter(rigid);
It is easy to use.
Disadvantage: Code of AdapterConst and Adapter will be very duplicated.
Solution A2 (+inheritance)
It is an improvement of the previous solution.
Let Adapter (has setPosition()) derive from AdapterConst (has getPosition()).
Disadvantage: It is not concise. I use 2 classes for the single task!
This might seem to be trivial, but in a bigger code-base, it is not fun at all.
Specifically, location of getPosition() will be far-away from setPosition(), e.g in different files.
This causes maintainability problem.
Solution B (template)
Create a template class. There are many ways e.g. :-
Adapter<T =RigidBody OR const RigidBody >
Adapter<bool=true is const OR false is non-const >
Disadvantage: In every ways, it is inelegant. It is an overkill. (?)
I will suffer from disadvantage of template e.g. everything in header.
Solution C1 (const_cast)
I am trying to avoid it. It is evil.
class Adapter{
public: RigidBody* rigid;
void setUnderlying(const RigidBody* r){
rigid=const_cast< RigidBody*>(r);
}
....
};
Solution C2 (+manual assert)
I can add some assertion manually.
It just emphasizes how much it is unprofessional :-
bool isConst;
void setUnderlying(const RigidBody* r){
...
isConst=true;
}
void setUnderlying(RigidBody* r){
...
isConst=false;
}
void setPosition(float a){
if(isConst){ /*throw some exception*/ }
....
}
Solution D (run away)
Lazy : change from test(constRigidBody* rigid) to test(RigidBody* rigid).
Crazy : change RigidBody::setPosition() to be const.
In either way, my program will not be const-correct any more,
but a single Adapter class would be enough.
Question
Do I really have to do one of these things wherever I encounter the const/non-const pattern?
Please provide a pretty solution. (no full code is required, but I don't mind)
Sorry for the long post.
Edit: In real life, Adapter is a parameter for many function.
It is passed around like a toy.
Most of such functions don't have knowledge about RigidBody, so it is not quite suitable to change from a bundle calling someFunction(adapter) to someFunction(offset,rigidbody).
You shouldn't keep with that idea. This is C++, not Java.
Your code is extremely Java oriented. I can see it by the way you write the code, use pointers and silently omit const when needed.
In fact, most of the bad C++ code that I personally saw is pretty much either written to be "C inside classes" or "Java without GC". Both of them are extremely bad ways of writing C++ code.
Your question has an idiomatic solution:
Ditch most of the design patterns. they are useful for languages where object are reference types by default. C++ prefers most of the times to tread object as value types and prefer static polymorphism (templates) rather than run-time polymorphism (inherit + override).
Write two classes , one is Adapter and one is ConstAdapter. This is what the standard library already does. every container has different iterator and const_iterator implementation exactly because of that reason. you can either store something by pointer, either by const pointer. It is error prone trying to mix the two. If there were a nice solution for that problem, we wouldn't have two iterator typedefs for each container.
A tightly controlled const_cast looks like a good solution to me:
// Only provides read-only access to the object
struct ConstAdapter {
int offset = 2;
// Constructible from const and non-const RigidBodies
ConstAdapter(RigidBody const *rigid)
: _rigid{rigid} { }
// Read-only interface
float getPosition() {
return rigid()->getPosition() + offset; //distort
}
// Hidden away for consistency with Adapter's API
// and to prevent swapping out an "actually non-const" RigidBody
// for a "truly const" one (see Adapter::rigid()`).
RigidBody const *rigid() const { return _rigid; }
private:
RigidBody const *_rigid;
};
// Inherits read-only functions, and provides write access as well
struct Adapter : ConstAdapter {
// Only constructible from a non-const RigidBody!
Adapter(RigidBody *rigid) : ConstAdapter{rigid} { }
// Write interface
void setPosition(float ppos){
return rigid()->setPosition(ppos-offset); //distort
}
// Here's the magic part: we know we can cast `const` away
// from our base class' pointer, since we provided it ourselves
// and we know it's not actually `const`.
RigidBody *rigid() const {
return const_cast<RigidBody *>(ConstAdapter::rigid());
}
};
Regarding:
Specifically, location of getPosition() will be far-away from setPosition(), e.g in different files.
This causes maintainability problem.
This is a non-issue. C++, unlike Java, allows multiple classes in a single file, and you are in fact encouraged to group such tightly related classes together. The declarations of the functions will be only a handful of lines apart, and their definitions can very well be grouped together in the corresponding .cpp file.
Use references instead of pointers, and let the const-ness propogate to the Adapter. Then you can safely const_cast, as
template <class Rigid>
class Adapter{
Rigid & rigid;
int offset;
public:
Adapter(Rigid & rigid, int offset = 2) : rigid(rigid), offset(offset) {}
float getPosition() const { return rigid.getPosition() + offset; }
void setPosition(float ppos) { rigid.setPosition(ppos - offset); }
};
My first instinct would be to access a RigidBody through an Adaptor and a const RigidBody through a const Adaptor. To achieve this, we use a factory to create the right kind of Adaptor, and in the implementation, we access the underlying RigidBody through an accessor method that (safely) casts only when allowed.
The code:
Start with the private members:
class Adaptor
{
RigidBody const& body;
int offset;
Adaptor(RigidBody body, int offset=2)
: body(body),
offset(offset)
{}
Adaptor(const Adaptor&) = delete;
The constructor is private, so we can only create instances through our factory. And we remove the copy constructor, so we can't create a non-const Adaptor from a const one.
Next, we have our first overloaded pair - the accessor used in the implementation. I've marked it protected, in case you want a range of similar adaptors. It could safely be public if you want, though.
protected:
RigidBody& get_body() { return const_cast<RigidBody&>(body); }
RigidBody const& get_body() const { return body; }
We know that the const_cast is safe, because we only get a non-const Adaptor from a non-const RigidBody, as we see in the other overloaded pair, which is the factory:
public:
static Adaptor *adapt(RigidBody& body, int offset = 2) { return new Adaptor{ body, offset }; }
static Adaptor const *adapt(RigidBody const& body, int offset = 2) { return new Adaptor{ body, offset }; }
From here on, each method is declared const unless it needs to modify the body, just as you'd expect. So, if you have a const Adaptor (which you will if you constructed it from a const RigidBody, you can't call any method that modifies body. And the implementation can't modify body from within any of the const methods.
float getPosition() const
{
// this uses the const get_body()
return get_body().getPosition() + offset;
}
void setPosition(float ppos)
{
// this uses the mutable get_body()
get_body().setPosition(ppos-offset);
}
You can demonstrate the safety by trying to modify body in a const method:
void illegal() const
{
get_body().setPosition(0); // error: passing ‘const RigidBody’ as ‘this’ argument discards qualifiers
body.setPosition(0); // error: passing ‘const RigidBody’ as ‘this’ argument discards qualifiers
}
};
Demo:
With a RigidBody, the adapter allows all operations; with a const RigidBody, the adapter allows only const operations:
#include <memory>
int main()
{
{
RigidBody b;
std::unique_ptr<Adaptor> a{Adaptor::adapt(b)};
a->setPosition(15.);
a->getPosition();
}
{
RigidBody const b;
std::unique_ptr<const Adaptor> a{Adaptor::adapt(b)};
a->setPosition(15.); // error: passing ‘const Adaptor’ as ‘this’ argument discards qualifiers
a->getPosition();
}
}
There's this one thing in C++ which has been making me feel uncomfortable for quite a long time, because I honestly don't know how to do it, even though it sounds simple:
How do I implement Factory Method in C++ correctly?
Goal: to make it possible to allow the client to instantiate some object using factory methods instead of the object's constructors, without unacceptable consequences and a performance hit.
By "Factory method pattern", I mean both static factory methods inside an object or methods defined in another class, or global functions. Just generally "the concept of redirecting the normal way of instantiation of class X to anywhere else than the constructor".
Let me skim through some possible answers which I have thought of.
0) Don't make factories, make constructors.
This sounds nice (and indeed often the best solution), but is not a general remedy. First of all, there are cases when object construction is a task complex enough to justify its extraction to another class. But even putting that fact aside, even for simple objects using just constructors often won't do.
The simplest example I know is a 2-D Vector class. So simple, yet tricky. I want to be able to construct it both from both Cartesian and polar coordinates. Obviously, I cannot do:
struct Vec2 {
Vec2(float x, float y);
Vec2(float angle, float magnitude); // not a valid overload!
// ...
};
My natural way of thinking is then:
struct Vec2 {
static Vec2 fromLinear(float x, float y);
static Vec2 fromPolar(float angle, float magnitude);
// ...
};
Which, instead of constructors, leads me to usage of static factory methods... which essentially means that I'm implementing the factory pattern, in some way ("the class becomes its own factory"). This looks nice (and would suit this particular case), but fails in some cases, which I'm going to describe in point 2. Do read on.
another case: trying to overload by two opaque typedefs of some API (such as GUIDs of unrelated domains, or a GUID and a bitfield), types semantically totally different (so - in theory - valid overloads) but which actually turn out to be the same thing - like unsigned ints or void pointers.
1) The Java Way
Java has it simple, as we only have dynamic-allocated objects. Making a factory is as trivial as:
class FooFactory {
public Foo createFooInSomeWay() {
// can be a static method as well,
// if we don't need the factory to provide its own object semantics
// and just serve as a group of methods
return new Foo(some, args);
}
}
In C++, this translates to:
class FooFactory {
public:
Foo* createFooInSomeWay() {
return new Foo(some, args);
}
};
Cool? Often, indeed. But then- this forces the user to only use dynamic allocation. Static allocation is what makes C++ complex, but is also what often makes it powerful. Also, I believe that there exist some targets (keyword: embedded) which don't allow for dynamic allocation. And that doesn't imply that the users of those platforms like to write clean OOP.
Anyway, philosophy aside: In the general case, I don't want to force the users of the factory to be restrained to dynamic allocation.
2) Return-by-value
OK, so we know that 1) is cool when we want dynamic allocation. Why won't we add static allocation on top of that?
class FooFactory {
public:
Foo* createFooInSomeWay() {
return new Foo(some, args);
}
Foo createFooInSomeWay() {
return Foo(some, args);
}
};
What? We can't overload by the return type? Oh, of course we can't. So let's change the method names to reflect that. And yes, I've written the invalid code example above just to stress how much I dislike the need to change the method name, for example because we cannot implement a language-agnostic factory design properly now, since we have to change names - and every user of this code will need to remember that difference of the implementation from the specification.
class FooFactory {
public:
Foo* createDynamicFooInSomeWay() {
return new Foo(some, args);
}
Foo createFooObjectInSomeWay() {
return Foo(some, args);
}
};
OK... there we have it. It's ugly, as we need to change the method name. It's imperfect, since we need to write the same code twice. But once done, it works. Right?
Well, usually. But sometimes it does not. When creating Foo, we actually depend on the compiler to do the return value optimisation for us, because the C++ standard is benevolent enough for the compiler vendors not to specify when will the object created in-place and when will it be copied when returning a temporary object by value in C++. So if Foo is expensive to copy, this approach is risky.
And what if Foo is not copiable at all? Well, doh. (Note that in C++17 with guaranteed copy elision, not-being-copiable is no problem anymore for the code above)
Conclusion: Making a factory by returning an object is indeed a solution for some cases (such as the 2-D vector previously mentioned), but still not a general replacement for constructors.
3) Two-phase construction
Another thing that someone would probably come up with is separating the issue of object allocation and its initialisation. This usually results in code like this:
class Foo {
public:
Foo() {
// empty or almost empty
}
// ...
};
class FooFactory {
public:
void createFooInSomeWay(Foo& foo, some, args);
};
void clientCode() {
Foo staticFoo;
auto_ptr<Foo> dynamicFoo = new Foo();
FooFactory factory;
factory.createFooInSomeWay(&staticFoo);
factory.createFooInSomeWay(&dynamicFoo.get());
// ...
}
One may think it works like a charm. The only price we pay for in our code...
Since I've written all of this and left this as the last, I must dislike it too. :) Why?
First of all... I sincerely dislike the concept of two-phase construction and I feel guilty when I use it. If I design my objects with the assertion that "if it exists, it is in valid state", I feel that my code is safer and less error-prone. I like it that way.
Having to drop that convention AND changing the design of my object just for the purpose of making factory of it is.. well, unwieldy.
I know that the above won't convince many people, so let's me give some more solid arguments. Using two-phase construction, you cannot:
initialise const or reference member variables,
pass arguments to base class constructors and member object constructors.
And probably there could be some more drawbacks which I can't think of right now, and I don't even feel particularly obliged to since the above bullet points convince me already.
So: not even close to a good general solution for implementing a factory.
Conclusions:
We want to have a way of object instantiation which would:
allow for uniform instantiation regardless of allocation,
give different, meaningful names to construction methods (thus not relying on by-argument overloading),
not introduce a significant performance hit and, preferably, a significant code bloat hit, especially at client side,
be general, as in: possible to be introduced for any class.
I believe I have proven that the ways I have mentioned don't fulfil those requirements.
Any hints? Please provide me with a solution, I don't want to think that this language won't allow me to properly implement such a trivial concept.
First of all, there are cases when
object construction is a task complex
enough to justify its extraction to
another class.
I believe this point is incorrect. The complexity doesn't really matter. The relevance is what does. If an object can be constructed in one step (not like in the builder pattern), the constructor is the right place to do it. If you really need another class to perform the job, then it should be a helper class that is used from the constructor anyway.
Vec2(float x, float y);
Vec2(float angle, float magnitude); // not a valid overload!
There is an easy workaround for this:
struct Cartesian {
inline Cartesian(float x, float y): x(x), y(y) {}
float x, y;
};
struct Polar {
inline Polar(float angle, float magnitude): angle(angle), magnitude(magnitude) {}
float angle, magnitude;
};
Vec2(const Cartesian &cartesian);
Vec2(const Polar &polar);
The only disadvantage is that it looks a bit verbose:
Vec2 v2(Vec2::Cartesian(3.0f, 4.0f));
But the good thing is that you can immediately see what coordinate type you're using, and at the same time you don't have to worry about copying. If you want copying, and it's expensive (as proven by profiling, of course), you may wish to use something like Qt's shared classes to avoid copying overhead.
As for the allocation type, the main reason to use the factory pattern is usually polymorphism. Constructors can't be virtual, and even if they could, it wouldn't make much sense. When using static or stack allocation, you can't create objects in a polymorphic way because the compiler needs to know the exact size. So it works only with pointers and references. And returning a reference from a factory doesn't work too, because while an object technically can be deleted by reference, it could be rather confusing and bug-prone, see Is the practice of returning a C++ reference variable, evil? for example. So pointers are the only thing that's left, and that includes smart pointers too. In other words, factories are most useful when used with dynamic allocation, so you can do things like this:
class Abstract {
public:
virtual void do() = 0;
};
class Factory {
public:
Abstract *create();
};
Factory f;
Abstract *a = f.create();
a->do();
In other cases, factories just help to solve minor problems like those with overloads you have mentioned. It would be nice if it was possible to use them in a uniform way, but it doesn't hurt much that it is probably impossible.
Simple Factory Example:
// Factory returns object and ownership
// Caller responsible for deletion.
#include <memory>
class FactoryReleaseOwnership{
public:
std::unique_ptr<Foo> createFooInSomeWay(){
return std::unique_ptr<Foo>(new Foo(some, args));
}
};
// Factory retains object ownership
// Thus returning a reference.
#include <boost/ptr_container/ptr_vector.hpp>
class FactoryRetainOwnership{
boost::ptr_vector<Foo> myFoo;
public:
Foo& createFooInSomeWay(){
// Must take care that factory last longer than all references.
// Could make myFoo static so it last as long as the application.
myFoo.push_back(new Foo(some, args));
return myFoo.back();
}
};
Have you thought about not using a factory at all, and instead making nice use of the type system? I can think of two different approaches which do this sort of thing:
Option 1:
struct linear {
linear(float x, float y) : x_(x), y_(y){}
float x_;
float y_;
};
struct polar {
polar(float angle, float magnitude) : angle_(angle), magnitude_(magnitude) {}
float angle_;
float magnitude_;
};
struct Vec2 {
explicit Vec2(const linear &l) { /* ... */ }
explicit Vec2(const polar &p) { /* ... */ }
};
Which lets you write things like:
Vec2 v(linear(1.0, 2.0));
Option 2:
you can use "tags" like the STL does with iterators and such. For example:
struct linear_coord_tag linear_coord {}; // declare type and a global
struct polar_coord_tag polar_coord {};
struct Vec2 {
Vec2(float x, float y, const linear_coord_tag &) { /* ... */ }
Vec2(float angle, float magnitude, const polar_coord_tag &) { /* ... */ }
};
This second approach lets you write code which looks like this:
Vec2 v(1.0, 2.0, linear_coord);
which is also nice and expressive while allowing you to have unique prototypes for each constructor.
You can read a very good solution in: http://www.codeproject.com/Articles/363338/Factory-Pattern-in-Cplusplus
The best solution is on the "comments and discussions", see the "No need for static Create methods".
From this idea, I've done a factory. Note that I'm using Qt, but you can change QMap and QString for std equivalents.
#ifndef FACTORY_H
#define FACTORY_H
#include <QMap>
#include <QString>
template <typename T>
class Factory
{
public:
template <typename TDerived>
void registerType(QString name)
{
static_assert(std::is_base_of<T, TDerived>::value, "Factory::registerType doesn't accept this type because doesn't derive from base class");
_createFuncs[name] = &createFunc<TDerived>;
}
T* create(QString name) {
typename QMap<QString,PCreateFunc>::const_iterator it = _createFuncs.find(name);
if (it != _createFuncs.end()) {
return it.value()();
}
return nullptr;
}
private:
template <typename TDerived>
static T* createFunc()
{
return new TDerived();
}
typedef T* (*PCreateFunc)();
QMap<QString,PCreateFunc> _createFuncs;
};
#endif // FACTORY_H
Sample usage:
Factory<BaseClass> f;
f.registerType<Descendant1>("Descendant1");
f.registerType<Descendant2>("Descendant2");
Descendant1* d1 = static_cast<Descendant1*>(f.create("Descendant1"));
Descendant2* d2 = static_cast<Descendant2*>(f.create("Descendant2"));
BaseClass *b1 = f.create("Descendant1");
BaseClass *b2 = f.create("Descendant2");
I mostly agree with the accepted answer, but there is a C++11 option that has not been covered in existing answers:
Return factory method results by value, and
Provide a cheap move constructor.
Example:
struct sandwich {
// Factory methods.
static sandwich ham();
static sandwich spam();
// Move constructor.
sandwich(sandwich &&);
// etc.
};
Then you can construct objects on the stack:
sandwich mine{sandwich::ham()};
As subobjects of other things:
auto lunch = std::make_pair(sandwich::spam(), apple{});
Or dynamically allocated:
auto ptr = std::make_shared<sandwich>(sandwich::ham());
When might I use this?
If, on a public constructor, it is not possible to give meaningful initialisers for all class members without some preliminary calculation, then I might convert that constructor to a static method. The static method performs the preliminary calculations, then returns a value result via a private constructor which just does a member-wise initialisation.
I say 'might' because it depends on which approach gives the clearest code without being unnecessarily inefficient.
Loki has both a Factory Method and an Abstract Factory. Both are documented (extensively) in Modern C++ Design, by Andei Alexandrescu. The factory method is probably closer to what you seem to be after, though it's still a bit different (at least if memory serves, it requires you to register a type before the factory can create objects of that type).
I don't try to answer all of my questions, as I believe it is too broad. Just a couple of notes:
there are cases when object construction is a task complex enough to justify its extraction to another class.
That class is in fact a Builder, rather than a Factory.
In the general case, I don't want to force the users of the factory to be restrained to dynamic allocation.
Then you could have your factory encapsulate it in a smart pointer. I believe this way you can have your cake and eat it too.
This also eliminates the issues related to return-by-value.
Conclusion: Making a factory by returning an object is indeed a solution for some cases (such as the 2-D vector previously mentioned), but still not a general replacement for constructors.
Indeed. All design patterns have their (language specific) constraints and drawbacks. It is recommended to use them only when they help you solve your problem, not for their own sake.
If you are after the "perfect" factory implementation, well, good luck.
This is my c++11 style solution. parameter 'base' is for base class of all sub-classes. creators, are std::function objects to create sub-class instances, might be a binding to your sub-class' static member function 'create(some args)'. This maybe not perfect but works for me. And it is kinda 'general' solution.
template <class base, class... params> class factory {
public:
factory() {}
factory(const factory &) = delete;
factory &operator=(const factory &) = delete;
auto create(const std::string name, params... args) {
auto key = your_hash_func(name.c_str(), name.size());
return std::move(create(key, args...));
}
auto create(key_t key, params... args) {
std::unique_ptr<base> obj{creators_[key](args...)};
return obj;
}
void register_creator(const std::string name,
std::function<base *(params...)> &&creator) {
auto key = your_hash_func(name.c_str(), name.size());
creators_[key] = std::move(creator);
}
protected:
std::unordered_map<key_t, std::function<base *(params...)>> creators_;
};
An example on usage.
class base {
public:
base(int val) : val_(val) {}
virtual ~base() { std::cout << "base destroyed\n"; }
protected:
int val_ = 0;
};
class foo : public base {
public:
foo(int val) : base(val) { std::cout << "foo " << val << " \n"; }
static foo *create(int val) { return new foo(val); }
virtual ~foo() { std::cout << "foo destroyed\n"; }
};
class bar : public base {
public:
bar(int val) : base(val) { std::cout << "bar " << val << "\n"; }
static bar *create(int val) { return new bar(val); }
virtual ~bar() { std::cout << "bar destroyed\n"; }
};
int main() {
common::factory<base, int> factory;
auto foo_creator = std::bind(&foo::create, std::placeholders::_1);
auto bar_creator = std::bind(&bar::create, std::placeholders::_1);
factory.register_creator("foo", foo_creator);
factory.register_creator("bar", bar_creator);
{
auto foo_obj = std::move(factory.create("foo", 80));
foo_obj.reset();
}
{
auto bar_obj = std::move(factory.create("bar", 90));
bar_obj.reset();
}
}
Factory Pattern
class Point
{
public:
static Point Cartesian(double x, double y);
private:
};
And if you compiler does not support Return Value Optimization, ditch it, it probably does not contain much optimization at all...
extern std::pair<std::string_view, Base*(*)()> const factories[2];
decltype(factories) factories{
{"blah", []() -> Base*{return new Blah;}},
{"foo", []() -> Base*{return new Foo;}}
};
I know this question has been answered 3 years ago, but this may be what your were looking for.
Google has released a couple of weeks ago a library allowing easy and flexible dynamic object allocations. Here it is: http://google-opensource.blogspot.fr/2014/01/introducing-infact-library.html
Let's say I have the following class:
class MyClass
{
private:
int Data;
public:
MyClass(int Init)
{
Data = Init;
}
int GetData() const
{
return Data;
}
};
Now, let's say I want to add a method that checks if Data is equal to zero. There are two ways to accomplish this:
bool DataIsZero() const
{
return Data == 0;
}
Or:
bool DataIsZero() const
{
return GetData() == 0;
}
Which is considered better practice? I can see how just using the variable itself might improve readability, but using the getter might make the code easier to maintain.
I don't really like getters/setters for reasons that I won't go into here. They're covered in other questions. However, since you've asked about them, my answer will assume that I use getters/setters; it will not visit all the possible alternatives.
I'd use the getter, for the maintenance reasons to which you allude. Indeed, the abstraction is half the purpose of having the getter in the first place (along with the slightly tighter access control).
If using the variable is more legible than using the getter, then your getter function name is poor and should be reconsidered.
As an aside, it's best to initialise members, not assign them in your constructor body after the fact. In fact, you have to do that with constants, so you might as well start now and remain consistent:
class MyClass
{
private:
int Data;
public:
MyClass(int Init) : Data(Init) {}
int GetData() const {
return Data;
}
};
See how the constructor has changed.
You should use the getter, because if your class moves to a more complex logic in the getter, then you will be insulated from the change. However, if your class provides a public getter, I'd question the logic of creating this method.
It depends.
The former is sufficient for simple classes.
The latter hides the implementation and can support polymorphism, if the method is virtual.