Fluent interface pattern and std::unique_ptr - c++

I am playing with the fluent interface pattern.
First, I wrote something like that:
class C
{
public:
C() { }
C* inParam1(int arg1){ param1 = arg1; return this; }
C* inParam2(int arg2){ param2 = arg2; return this; }
private:
int param1;
int param2;
}
Then I tried to use the std::unique_ptr, but then I realized that I do not know how to "shift" the pointer (this) along the chain. I tried something like:
return std::move(this);
that of course does not work.
How can I do this? Are there any problems doing something like this?
In order to reply to comments like: "do not use pointers": there isn't (yet) any practical reason because I am doing this with pointers, is just something I wonder if can be done this way.

Why do you have to return pointers at all?
class C
{
public:
C create() { return C(); }
C & inParam1(int arg1){ param1 = arg1; return *this; }
C & inParam2(int arg2){ param2 = arg2; return *this; }
private:
C() { }
int param1;
int param2;
};
I must admit I don't understand the purpose of that create function or why the constructor is private or how you actually create objects of this class at all. In my understanding, the class should actually be like this:
class C
{
public:
C() {}
C & inParam1(int arg1){ param1 = arg1; return *this; }
C & inParam2(int arg2){ param2 = arg2; return *this; }
private:
int param1;
int param2;
};
And used like this:
int main()
{
C().inParam1(10).inParam2(20).whatever();
}

There can be only one std::unique_ptr instance for any given instance (because each would try to delete it and that can be done only once). Therefore, while create can return a std::unique_ptr, the other two methods cannot.
Is there any reason why you don't have the other methods return a reference rather than a pointer? And why don't you just have a public constructor? I don't see the value of the create method in this example.

You missed one important think from the c++ fluent interface example :
//it doesn't make sense to chain after create(), so don't return *this
Therefore, you shouldn't return anything from your create() method.
However if you still want to return something, at least do not (mis-)use unique_ptr, and just return a new object :
C create() { return C(); }

Related

Declare one object to be of multiple classes, depending on a condition

This question is based on Create objects in conditional c++ statements.
However, in my case I need to declare one object from a choice of multiple classes which will then be passed as argument to a function. Hence, the object has to be declared with a pre-defined name (obj in this case).
Class1 obj;
Class2 obj;
if (...) {
obj = Class1(); }
if (...) {
obj = Class1(a, b); }
else
obj = Class2();
// Do something on declared object
DoSomething(obj.variable_);
Currently the above will not work because of conflicting declaration of obj. How should I go about doing this?
You might not need std::variant, if your object doesn't have to be "polymorphic" at run-time. Refactor your code to:
if (...) {
DoSomething(Class1());
if (...) {
DoSomething(Class1(a, b));
else
DoSomething(Class2());
And make DoSomething a template or overload set:
void DoSomething(const Class1&) { }
void DoSomething(const Class2&) { }
You can use std::variant.
std::variant<Class1, Class2> var;
if (...) {
var = Class1(); }
if (...) {
var = Class1(a, b); }
else
var = Class2();
std::visit([](auto&& obj) { DoSomething(obj.variable_); }, var);
The variant can hold one of the alternatives at a time, which is what you need. And std::visit will let you apply code generically to either alternative, so long as the generic lambda can be applied to it.
Solution using simple polymorphism,
ClassBase () {
}
Class1 : ClassBase (){
}
Class2 : ClassBase (){
}
Then you can use like,
ClassBase obj;
if (...) {
obj = Class1(); }
if (...) {
obj = Class1(a, b); }
else
obj = Class2();
// Do something on declared object
DoSomething(obj.variable_);
The OP said: "Class1 and Class2 can inherit from a common base class. I can provide overload of DoSomething"
Inheritance is OK. But only if it is in a form of "subtyping". Let's assume everyone is aware of that. Canonical example.
In this case OP's question and code is actually internals of a factory method. One solution might be:
Interface::ptr make ( Interface::subtype which)
{
if ( which == Interface::subtype::one )
return std::make_unique<Class1>();
return std::make_unique<Class2>();
}
And the usage is simple:
Interface::ptr one = make( Interface::subtype::one ) ;
Interface::ptr two = make( Interface::subtype::two ) ;
one->do_something() ;
two->do_something() ;
Jut one variant of the common concept. Working code is here.
Option with no polymorphism required
Is allways a good option. We do not need inheritance. We just need intances that do understand the message do_something().
// no inheritance required
template<typename T>
void do_something( T the_t_ ) { the_t_.do_something(); }
Ditto
if ( ... ) {
do_something(Class1{}) ;
}
else if ( ... ) {
do_something(Class1(a,b)) ;
} else {
do_something(Class2());
}
In that case Class1 and Class2 do not need a common base type.
ps: Vittorio's solution is very good. It can be also applied when Class1 and Class2 are completely unrelated.
An interesting variant of that variant could be:
if (...) {
Class1();
if (...) {
Class1(a, b);
else
Class2();
No function overloads DoSomething() but type instances that "do something". Might be the most feasible design but only for some app's.

Getting same class instance as attribute from another class

I would like to obtain an class instance from another class.
I have the following classes, with class A having B object as a private member.
class A
{
private:
B my_B;
public:
B getBInstance (void)
{
return this->my_B;
}
}
class B
{
private:
int my_attr;
public:
B ()
{
this -> my_attr = 0; //Initial value for my_attr
}
void setMyAttr (int attr)
{
this->my_attr = attr;
}
int getMyAttr (void)
{
return this->my_attr;
}
}
I want my_B to be exclusive to an object that is instantiated from class A.
When I perform the following, I am not able to change the contents of my_attr, because it accesses a different B instance everytime I call A::getBInstance().
A new_A;
new_A.getBInstance().setMyAttr(50);
printf ("%d\n", new_A.getBInstance().getMyAttr()); //Prints 0
But, if I do the following, then I get the correct output:
A new_A;
new_B = new_A.getBInstance();
new_B.setMyAttr (50);
printf ("%d\n", newB.getMyAttr()); //Prints 50
I apologize if the answer is so obvious. I suspect efforts regarding making things static or singleton pattern might help, yet I need some guidance, as I'm pretty new to this kind of implementations.
Thanks in advance,
You're returning a copy of my_B. If you want to change the one stored in A, return a reference:
B &getBInstance (void)
{
return this->my_B;
}

Inheritance and pointers

I have code like this:
class Human
{
protected:
int age;
std::string sex;
public:
virtual void speak() = 0;
};
class Child:public Human
{
public:
void speak(){std::cout << "I am Child\n";}
};
class Man:public Human
{
public:
void speak(){std::cout << "I am Man\n";}
};
class Woman:public Human
{
public:
void speak(){std::cout << "I am Woman\n";}
};
(don't know, std::shared_ptr<Human> maybe?) operator*(std::shared_ptr<Child> &b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man")
{
return (i want b to become std::shared_ptr<Man>)
}
if(b->getAge()>18 && b->getSex()=="Woman")
{
return (here I want b to become std::shared_ptr<Woman>);
}
return;
}
int main(){
auto x = std::make_shared<Child>;
x*19;
}
I know it seems odd, but it's the simplest case i can think of, without having to write down all code i'm struggling with rn. Could someone explain, what type should overload be and how to change shared_ptr type, knowing they derive from same parent?
Objects cannot change type. A Child object will always be a Child object. What you can do is create a new object with the properties you want and return that:
std::shared_ptr<Human> operator*(std::shared_ptr<Human> b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man") {
return std::make_shared<Man>(b->getAge());
} else if(b->getAge()>18 && b->getSex()=="Woman") {
return std::make_shared<Woman>(b->getAge());
} else {
return b;
}
}
int main(){
std::shared_ptr<Human> x = std::make_shared<Child>;
x = x*19;
}
This doesn't seem like a good design though. A Human's status as a child or adult would be better represented as an attribute of the object or by a function that checks if age is greater than 18.
You cannot make the type T<Derived> inherit from T<Base> because C++ templates do not support covariance. To do so would be unsafe for certain types, such as mutable references to containers. (Imagine taking a reference to std::vector<Cat> as std::vector<Animal>& and pushing back a dog!)
(I would make this answer a comment, but I don't have comment abilities.)
Update:
You can write a non-template wrapper that handles heap data:
class Wrapper
{
public:
Wrapper(Base* b) : raw(b) {}
~Wrapper() { delete raw; }
Base& get() { return *base; }
private:
Base* raw;
}
Of course, in your example, you use std::shared_ptr and not std::unique_ptr. You would have to handle reference counting instead of simply deleting the data in the destructor, but the technique of keeping an internal raw pointer still stands.
Update 2:
The above code could be used as is to provide a level of indirection, such that all classes that inherit from the base class may be held in the same type, without writing your own reference counter:
std::shared_ptr<Wrapper>
This solution may be seen as similar to doing std::shared_ptr<Base*>, except that the latter solution would leak memory.

Complicated test to check which object instantiates a function call

I have a struct ( can be class ) and is defined in another class as shown
struct A{
somedata_A;
somespecificimplementation_A(someclass *S1);
};
class someclass{
somedata_someclass;
A a;
};
main(){
someclass c1, *c2;
c2 = &c1;
c1.a.somespecificimplementation_A(c2);
}
How do I verify that c2 is indeed a reference for c1? Pardon me for putting up this example as it is obvious that c2 is reference for c1.
Update: A does not store a pointer to someclass
If you don't know nothing about parent, compare member' adresses
void A::somespecificimplementation_A(someclass *S1)
{
if (this == &(S1->a)) {
// parent == S1
} else {
// parent != S1
}
}
Like that:
struct A{
int somedata_A;
int somespecificimplementation_A(someclass *S1){
if ((void*) &(S1->a) == this)
{
std::cout << "S1 is a pointer to myself" << std::endl;
return 1;
}
return 0;
}
};
Assuming struct A has a pointer to c1, you can then take a pointer to c2 and compare pointer values? Similar to what you would do with assignment operator overloads?
Why go the way around and pass a pointer of your class to the nested struct which you then have to test, when you can instead give a reference to the parent by the parent during its construction?
class someclass
{
public:
struct a
{
void foo()
{
parent.doSomething();
}
private:
friend someclass;
a(someclass & parent)
: parent(parent)
{}
someclass & parent;
} a;
someclass() : a(*this) {}
private:
void doSomething()
{
}
};
Although technically unspecified, the following will work on
most modern, general purpose machines:
void A::somespecificimplementation_A( someclass* S1 )
{
char const* s = reinterpret_cast<char const*>( S1 );
char const* t = reinterpret_cast<char const*>( this );
if ( this >= s && this < s + sizeof( someclass ) ) {
// This A is a member of S1
} else {
// This A isn't
}
}
Having said that, I would stress:
This is not specified by the standard. It will work on
machines with a flat, linear addressing, but may fail (give
false positives) on a machine with e.g. segmented memory.
I'd seriously question the design if A needs to know who it
is a member of.
And if A really does need this information, it really should store
a pointer to someclass, which is passed in to its constructor, so that the dependency is manifest.

How to return a class object by reference in C++?

I have a class called Object which stores some data.
I would like to return it by reference using a function like this:
Object& return_Object();
Then, in my code, I would call it like this:
Object myObject = return_Object();
I have written code like this and it compiles. However, when I run the code, I consistently get a seg fault. What is the proper way to return a class object by reference?
You're probably returning an object that's on the stack. That is, return_Object() probably looks like this:
Object& return_Object()
{
Object object_to_return;
// ... do stuff ...
return object_to_return;
}
If this is what you're doing, you're out of luck - object_to_return has gone out of scope and been destructed at the end of return_Object, so myObject refers to a non-existent object. You either need to return by value, or return an Object declared in a wider scope or newed onto the heap.
You can only use
Object& return_Object();
if the object returned has a greater scope than the function. For example, you can use it if you have a class where it is encapsulated. If you create an object in your function, use pointers. If you want to modify an existing object, pass it as an argument.
class MyClass{
private:
Object myObj;
public:
Object& return_Object() {
return myObj;
}
Object* return_created_Object() {
return new Object();
}
bool modify_Object( Object& obj) {
// obj = myObj; return true; both possible
return obj.modifySomething() == true;
}
};
You can only return non-local objects by reference. The destructor may have invalidated some internal pointer, or whatever.
Don't be afraid of returning values -- it's fast!
I will show you some examples:
First example, do not return local scope object, for example:
const string &dontDoThis(const string &s)
{
string local = s;
return local;
}
You can't return local by reference, because local is destroyed at the end of the body of dontDoThis.
Second example, you can return by reference:
const string &shorterString(const string &s1, const string &s2)
{
return (s1.size() < s2.size()) ? s1 : s2;
}
Here, you can return by reference both s1 and s2 because they were defined before shorterString was called.
Third example:
char &get_val(string &str, string::size_type ix)
{
return str[ix];
}
usage code as below:
string s("123456");
cout << s << endl;
char &ch = get_val(s, 0);
ch = 'A';
cout << s << endl; // A23456
get_val can return elements of s by reference because s still exists after the call.
Fourth example
class Student
{
public:
string m_name;
int age;
string &getName();
};
string &Student::getName()
{
// you can return by reference
return m_name;
}
string& Test(Student &student)
{
// we can return `m_name` by reference here because `student` still exists after the call
return stu.m_name;
}
usage example:
Student student;
student.m_name = 'jack';
string name = student.getName();
// or
string name2 = Test(student);
Fifth example:
class String
{
private:
char *str_;
public:
String &operator=(const String &str);
};
String &String::operator=(const String &str)
{
if (this == &str)
{
return *this;
}
delete [] str_;
int length = strlen(str.str_);
str_ = new char[length + 1];
strcpy(str_, str.str_);
return *this;
}
You could then use the operator= above like this:
String a;
String b;
String c = b = a;
Well, it is maybe not a really beautiful solution in the code, but it is really beautiful in the interface of your function. And it is also very efficient. It is ideal if the second is more important for you (for example, you are developing a library).
The trick is this:
A line A a = b.make(); is internally converted to a constructor of A, i.e. as if you had written A a(b.make());.
Now b.make() should result a new class, with a callback function.
This whole thing can be fine handled only by classes, without any template.
Here is my minimal example. Check only the main(), as you can see it is simple. The internals aren't.
From the viewpoint of the speed: the size of a Factory::Mediator class is only 2 pointers, which is more that 1 but not more. And this is the only object in the whole thing which is transferred by value.
#include <stdio.h>
class Factory {
public:
class Mediator;
class Result {
public:
Result() {
printf ("Factory::Result::Result()\n");
};
Result(Mediator fm) {
printf ("Factory::Result::Result(Mediator)\n");
fm.call(this);
};
};
typedef void (*MakeMethod)(Factory* factory, Result* result);
class Mediator {
private:
Factory* factory;
MakeMethod makeMethod;
public:
Mediator(Factory* factory, MakeMethod makeMethod) {
printf ("Factory::Mediator::Mediator(Factory*, MakeMethod)\n");
this->factory = factory;
this->makeMethod = makeMethod;
};
void call(Result* result) {
printf ("Factory::Mediator::call(Result*)\n");
(*makeMethod)(factory, result);
};
};
};
class A;
class B : private Factory {
private:
int v;
public:
B(int v) {
printf ("B::B()\n");
this->v = v;
};
int getV() const {
printf ("B::getV()\n");
return v;
};
static void makeCb(Factory* f, Factory::Result* a);
Factory::Mediator make() {
printf ("Factory::Mediator B::make()\n");
return Factory::Mediator(static_cast<Factory*>(this), &B::makeCb);
};
};
class A : private Factory::Result {
friend class B;
private:
int v;
public:
A() {
printf ("A::A()\n");
v = 0;
};
A(Factory::Mediator fm) : Factory::Result(fm) {
printf ("A::A(Factory::Mediator)\n");
};
int getV() const {
printf ("A::getV()\n");
return v;
};
void setV(int v) {
printf ("A::setV(%i)\n", v);
this->v = v;
};
};
void B::makeCb(Factory* f, Factory::Result* r) {
printf ("B::makeCb(Factory*, Factory::Result*)\n");
B* b = static_cast<B*>(f);
A* a = static_cast<A*>(r);
a->setV(b->getV()+1);
};
int main(int argc, char **argv) {
B b(42);
A a = b.make();
printf ("a.v = %i\n", a.getV());
return 0;
}
It isn't really good practice to return an initiated object as it does go out of scope. There are rare instances that this is the desired option. It actually can be done if the class is a referencing counting smart pointer or some other smart pointer.
How does a reference-counting smart pointer's reference counting work?