How to overcome object slicing in repository pattern? [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I have the following piece of code:
#include <iostream>
class AnimalRepository {
public:
virtual ~AnimalRepository() = default;
virtual auto makeSound() -> void {
std::cout << "Null" << std::endl;
}
};
class CatRepository: public AnimalRepository {
public:
auto makeSound() -> void override {
std::cout << "Meow" << std::endl;
}
};
class DogRepository: public AnimalRepository {
public:
auto makeSound() -> void override {
std::cout << "Woof" << std::endl;
}
};
class Animal {
public:
explicit Animal(const AnimalRepository& repository)
: repository(repository) {
}
auto makeSound() -> void {
return repository.makeSound();
}
protected:
AnimalRepository repository;
};
Animal cat = Animal(CatRepository());
Animal dog = Animal(DogRepository());
int main() {
cat.makeSound();
dog.makeSound();
};
I expected the main function to output the respective cat and dog method override functions, but instead it always returns "Null". I believe this is a case of object slicing, and I'm not quite sure I understand why the reference pointer in the Animal class constructor doesn't avoid this issue.

The slicing is done here: AnimalRepository repository;. This can't contain a subclass because it is an instance and not a reference or pointer. It is easiest to replace this with a unique smart pointer pointing to a copy of the input.

Or move the whole pattern from dynamic polymorphism to (compile time) static polymorphism
#include <iostream>
class CatBehavior
{
public:
auto makeSound() -> void
{
std::cout << "Meow" << std::endl;
}
};
class DogBehavior
{
public:
auto makeSound() -> void
{
std::cout << "Woof" << std::endl;
}
};
template<typename behavior_t>
class Animal
{
public:
explicit Animal()
{
}
auto makeSound() -> void
{
return m_behavior.makeSound();
}
protected:
behavior_t m_behavior;
};
int main()
{
Animal<CatBehavior> cat;
Animal<DogBehavior> dog;
cat.makeSound();
dog.makeSound();
};

Related

Casting 1st Derived Class to 2nd Derived Class - Why does it work?

I simply created two derived class from a base class.
Then created an object of a derived class and converted into base class.
Then from the base class, i converted to derived class number two,
I was hoping it won't work, but it did.
Can someone please explain me how below code is working... And How do I prevent this from happening...
PS: Now edited the Program to make bit more sense.
Also this is the situation I want to avoid if possible:
class Animal
{
public:
Animal() { std::cout << "I am an animal\r\n"; };
virtual void makeSound() = 0;
~Animal() = default;
};
class Cat : public Animal
{
public:
Cat() { std::cout << "I am a Cat\r\n"; };
void makeSound() final { std::cout << "Meaow\r\n"; }
~Cat() = default;
};
class Dog : public Animal
{
public:
Dog() { std::cout << "I am a Dog\r\n"; };
void makeSound() final { std::cout << "Bark\r\n"; }
~Dog() = default;
};
template<typename baseType, typename derivedType>
std::unique_ptr<derivedType> dynamicConvert(std::unique_ptr<baseType> baseObj)
{
auto tmp = dynamic_cast<derivedType*>(baseObj.get());
std::unique_ptr<derivedType> derivedPointer;
if (tmp != nullptr)
{
baseObj.release();
derivedPointer.reset(tmp);
}
return derivedPointer;
}
int main()
{
auto cat = std::make_unique<Cat>();
auto base = dynamicConvert<Cat, Animal>(std::move(cat));
base->makeSound();
auto dog = dynamicConvert<Animal, Dog>(std::move(base));
dog->makeSound();
return 0;
}
Output:
I am an animal
I am a Cat
Meaow
Bark
You can't, that's part of the contract with static_cast. It is resolved at compile time, and thus will not check at runtime that you didn't make a mistake: casting to the wrong type just triggers UB.
Use dynamic_cast when you want runtime-checked conversions.

C++ diamond problem - How to call base method only once

I'm using multiple inheritance in C++ and extending base methods by calling their base explicitly. Assume the following hierarchy:
Creature
/ \
Swimmer Flier
\ /
Duck
Which corresponds to
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Flier::print();
Swimmer::print();
std::cout << "I'm a duck" << std::endl;
}
};
Now this presents a problem - calling the duck's print method calls its respective base methods, all of which in turn call the Creature::print() method, so it ends up being called twice-
I'm a creature
I can fly
I'm a creature
I can swim
I'm a duck
I would like to find a way to make sure the base method is called only once. Something similar to the way virtual inheritance works (calling the base constructor on the first call, then only assigning a pointer to it on successive calls from other derived classes).
Is there some built-in way to do this or do we need to resort to implementing one ourselves?
If so, how would you approach this?
The question isn't specific to printing. I wondered if there's a mechanism for extending base methods and functionality while keeping the call order and avoiding the diamond problem.
I understand now that the most prominent solution would be to add helper methods, but I just wondered if there's a "cleaner" way.
Most likely this is a XY problem. But ... just don't call it twice.
#include <iostream>
class Creature
{
public:
virtual void identify()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a swimmer\n";
}
virtual void tell_ability()
{
std::cout << "I can swim\n";
}
};
class Flier : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a flier\n";
}
virtual void tell_ability()
{
std::cout << "I can fly\n";
}
};
class Duck : public Flier, public Swimmer
{
public:
virtual void tell_ability() override
{
Flier::tell_ability();
Swimmer::tell_ability();
}
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a duck\n";
}
};
int main()
{
Creature c;
c.identify();
std::cout << "------------------\n";
Swimmer s;
s.identify();
std::cout << "------------------\n";
Flier f;
f.identify();
std::cout << "------------------\n";
Duck d;
d.identify();
std::cout << "------------------\n";
}
Output:
I'm a creature
------------------
I'm a creature
I can swim
I'm a swimmer
------------------
I'm a creature
I can fly
I'm a flier
------------------
I'm a creature
I can fly
I can swim
I'm a duck
------------------
We can let the base class keep track of the attributes:
#include <iostream>
#include <string>
#include <vector>
using namespace std::string_literals;
class Creature
{
public:
std::string const attribute{"I'm a creature"s};
std::vector<std::string> attributes{attribute};
virtual void print()
{
for (auto& i : attributes)
std::cout << i << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { attributes.push_back(attribute); }
std::string const attribute{"I can swim"s};
};
class Flier : public virtual Creature
{
public:
Flier() { attributes.push_back(attribute); }
std::string const attribute{"I can fly"s};
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { attributes.push_back(attribute); }
std::string const attribute{"I'm a duck"s};
};
int main()
{
Duck d;
d.print();
}
Likewise, if it is not just printing we're after, but rather the function calls, then we could let the base class keep track of the functions:
#include <iostream>
#include <functional>
#include <vector>
class Creature
{
public:
std::vector<std::function<void()>> print_functions{[this] {Creature::print_this(); }};
virtual void print_this()
{
std::cout << "I'm a creature" << std::endl;
}
void print()
{
for (auto& f : print_functions)
f();
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { print_functions.push_back([this] {Swimmer::print_this(); }); }
void print_this()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
Flier() { print_functions.push_back([this] {Flier::print_this(); }); }
void print_this()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { print_functions.push_back([this] {Duck::print_this(); }); }
void print_this()
{
std::cout << "I'm a duck" << std::endl;
}
};
int main()
{
Duck d;
d.print();
}
An easy way is to create a bunch of helper classes that mimick the inheritance structure of your main hierarchy and do all the printing in their constructors.
struct CreaturePrinter {
CreaturePrinter() {
std::cout << "I'm a creature\n";
}
};
struct FlierPrinter: virtual CreaturePrinter ...
struct SwimmerPrinter: virtual CreaturePrinter ...
struct DuckPrinter: FlierPrinter, SwimmerPrinter ...
Then each print method in the main hierarchy just creates the corresponding helper class. No manual chaining.
For maintainability you can make each printer class nested in its corresponding main class.
Naturally in most real world cases you want to pass a reference to the main object as an argument to the constructor of its helper.
Your explicit calls to the print methods form the crux of the issue.
One way round this would be to drop the print calls, and replace them with say
void queue(std::set<std::string>& data)
and you accumulate the print messages into the set. Then it doesn't matter those functions in the hierarchy get called more than once.
You then implement the printing of the set in a single method in Creature.
If you want to preserve the order of printing, then you'd need to replace the set with another container that respects the order of insertion and rejects duplicates.
If you want that middle class method, do not call the base class method. The easiest and simplest way is to extract extra methods, and then reimplementing Print is easy.
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Creature::Print();
Flier::detailPrint();
Swimmer::detailPrint();
detailPrint();
}
void detailPrint()
{
std::cout << "I'm a duck" << std::endl;
}
};
Without details what is your actual problem is, it hard to come up with a better solution.
Use:
template<typename Base, typename Derived>
bool is_dominant_descendant(Derived * x) {
return std::abs(
std::distance(
static_cast<char*>(static_cast<void*>(x)),
static_cast<char*>(static_cast<void*>(dynamic_cast<Base*>(x)))
)
) <= sizeof(Derived);
};
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Walker : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can walk" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer, public Walker
{
public:
void print()
{
Walker::print();
Swimmer::print();
Flier::print();
std::cout << "I'm a duck" << std::endl;
}
};
And with Visual Studio 2015 the output is:
I'm a creature
I can walk
I can swim
I can fly
I'm a duck
But is_dominant_descendant does not have a portable definition. I wish it were a standard concept.
You are asking for something like inheritance on a function level that automatically calls the inherited function and just adds more code. Also you want it to be done in a virtual way just like class inheritance. Pseudo syntax:
class Swimmer : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
// Inherit from both prints. As they were created using "virtual function inheritance",
// this will "mix" them just like in virtual class inheritance
void print() : Flier::print(), Swimmer::print()
{
std::cout << "I'm a duck" << std::endl;
}
};
So the answer to your question
Is there some built-in way to do this?
is no. Something like this does not exist in C++. Also, I'm not aware of any other language that has something like this. But it is an interesting idea...

C++ : calling an abstract base class constructor / undefined symbol in shared object

I am trying to use abstract classes and I met some problems when defining constructors of derived class. I wrote the following code, based on the answer to this question.
#include <string>
#include <iostream>
class ICommand {
private:
ICommand();
public:
const std::string name;
ICommand(const std::string& name) : name(name) { }
virtual void callMe();
virtual void callMe2();
};
class MyCommand : public ICommand {
public:
int x;
MyCommand(const std::string& name) : ICommand(name) { }
MyCommand(const std::string& name, int x) : ICommand(name), x(x) { }
void callMe() {
std::cout << name << "\n";
}
void callMe2() {
std::cout << name << x << "\n";
}
};
void f(std::string name) {
MyCommand A(name);
A.callMe();
}
This compiles without error. However my aim is to build a .so for a R package). In the R installation process, the .so is build without error, with clang++ -shared, but then there is a verification step which produces
unable to load shared object '/path/object.so':
/path/object.so: undefined symbol: _ZTI8ICommand
I've met this kind of problem before, and there are workarounds — not calling Icommand(name) is fairly simple, but I want to understand what is happening there, and, if possible, how to avoid the workaround.
Thanks in advance for your thoughts.
Answer
For the convenience of future readers: the only necessary change here is to replace the definition of virtual functions in the abstract class by
virtual void callMe() = 0;
virtual void callMe2() = 0;
which makes them pure virtual functions. Why this settles the problem totally beats me.
With the:
class MyClass {
private:
MyClass();
};
You are deleting a default constructor. If you want to call a default constructor then (declare or) define or don't define one but don't delete it. Your derived class default constructor will call the base class default constructor:
#include <string>
#include <iostream>
#include <memory>
class ICommand {
public:
std::string name;
ICommand() : name("The name") { std::cout << "Default base class constructor." << std::endl; }
virtual void callMe() = 0;
};
class MyCommand : public ICommand {
public:
MyCommand(){ std::cout << "Default derived class constructor." << std::endl; };
void callMe() override {
std::cout << name << std::endl;
}
};
void f2(const std::string& name) {
std::shared_ptr<ICommand> p = std::make_shared<MyCommand>();
p->callMe();
}
int main(){
f2("asdasd");
}
Part 2:
If you are trying to use the above classes in a polymorphic way then make your ICommand member functions pure virtual:
virtual void callMe() = 0;
virtual void callMe2() = 0;
Modify the void f function to:
void f(const std::string& name) {
std::shared_ptr<ICommand> p = std::make_shared<MyCommand>(name);
p->callMe();
}
Live example on Coliru.
class ICommand {
private:
ICommand() = default;
public:
const std::string name;
ICommand(const std::string& name) : name(name) { }
virtual ~ICommand() = default;
virtual void callMe() = 0;
virtual void callMe2() = 0;
};

Injecting a function into a subclass

Is it possible to do such things in C++14. I have a base class as follows:
#include <iostream>
class AbstractElement;
class ConcreteElement;
class SuperConcreteElement;
class B
{
public:
void bar(AbstractElement*)
{
std::cout << "Abstract element" << std::endl;
}
void bar(ConcreteElement*)
{
std::cout << "Concrete element" << std::endl;
}
void bar(SuperConcreteElement*)
{
std::cout << "Super concrete element" << std::endl;
}
};
class AbstractElement
{
public:
virtual void foo() = 0;
};
class ConcreteElement : public AbstractElement
{
private:
B _b;
public:
void foo()
{
_b.bar(this); //1
}
};
class SuperConcreteElement : public AbstractElement
{
private:
B _b;
public:
void foo()
{
_b.bar(this); //2
}
};
int main()
{
AbstractElement *e = new ConcreteElement();
e -> foo(); //Prints Concrete element
}
As you can see at //1 and //2, the function's body is completely similar. But I can't quite move it into a base class because of depending on the static type of this. In spite of that fact, I wouldn't like to write absolutely the same code every time I need to add one more subclass of AbstractElement. So, I need some kind of mechanism which provides us with the facility to inject code into a function.
As long as marcos are not very desirable solution, I'd like to ask about some tricks that can be done in C++14 for solving such a problem.
Yes, it is possible using CRTP:
#include <iostream>
class AbstractElement;
class ConcreteElement;
class SuperConcreteElement;
class B
{
public:
void bar(AbstractElement*)
{
std::cout << "Abstract element" << std::endl;
}
void bar(ConcreteElement*)
{
std::cout << "Concrete element" << std::endl;
}
void bar(SuperConcreteElement*)
{
std::cout << "Super concrete element" << std::endl;
}
};
class AbstractElement
{
public:
virtual void foo() = 0;
};
template <class T>
class CRTPAbstractElement : public AbstractElement
{
B _b;
public:
virtual void foo()
{
T* t = dynamic_cast<T *>(this);
_b.bar(t);
}
};
class ConcreteElement : public CRTPAbstractElement<ConcreteElement>
{
};
class SuperConcreteElement : public CRTPAbstractElement<SuperConcreteElement>
{
};
int main()
{
AbstractElement *e = new ConcreteElement();
e -> foo(); //Prints Concrete element
}
By adding an intermediate CRTP class we are able to cast a pointer to the base class to a pointer to the derived class. Thus solving the issue of code duplication.

C+11 Strategy Pattern with state

An example of Strategy Pattern from the book, Head First Design Patterns, was written in C++ at [here]. I'm practicing to transform it into C++11 style according to Effective GoF Patterns with C++11 and Boost as showing below.
The Quack behavior:
struct Quack {
static void quack()
{
std::cout << __FUNCTION__ << std::endl;
}
};
struct MuteQuack {
static void quack()
{
std::cout << __FUNCTION__ << std::endl;
}
};
The Fly behavior:
struct FlyWithWings {
public:
static void fly()
{
std::cout << __FUNCTION__ << std::endl;
}
};
struct FlyNoWay {
public:
static void fly()
{
std::cout << __FUNCTION__ << std::endl;
}
};
The Duck hierarchy:
class Duck
{
public:
typedef std::function<void(void)> QUACK;
typedef std::function<void(void)> FLY;
public:
Duck(const QUACK &q, const FLY &f)
: m_Quack(q), m_Fly(f) {}
virtual ~Duck()
{
}
void perform_quack()
{
m_Quack();
}
void perform_fly()
{
m_Fly();
}
protected:
QUACK m_Quack;
FLY m_Fly;
private:
Duck(const Duck&) = delete;
Duck& operator=(const Duck&) = delete;
};
class MallardDuck
: public Duck
{
public:
MallardDuck()
: Duck(&Quack::quack, &FlyWithWings::fly)
{
}
};
class PaintedDuck
: public Duck
{
public:
PaintedDuck()
: Duck(&MuteQuack::quack, &FlyNoWay::fly)
{
}
};
So far so good, the client works well.
int main()
{
MallardDuck x1;
x1.perform_quack();
x1.perform_fly();
PaintedDuck x2;
x2.perform_quack();
x2.perform_fly();
return 0;
}
Now I would like to extend to a new class RubberDuck to Duck hierarchy, and the RubberDuck uses a new fly behavior FlyWithRocket which has a object state. As following:
A new Fly behavior:
class FlyWithRocket {
public:
FlyWithRocket() : m_Energy(3) {}
void fly()
{
if(m_Energy > 0)
{
fly_with_rocket();
--m_Energy;
}
else
{
fly_out_of_energy();
}
}
private:
void fly_with_rocket()
{
std::cout << __FUNCTION__ << std::endl;
}
void fly_out_of_energy()
{
std::cout << __FUNCTION__ << std::endl;
}
unsigned int m_Energy;
};
A new Duck type:
class RubberDuck
: public Duck
{
public:
RubberDuck()
: Duck(&MuteQuack::quack, std::bind(&FlyWithRocket::fly, std::ref(m_flyrocket)))
, m_flyrocket()
{
}
private:
FlyWithRocket m_flyrocket;
};
From now I'm wondering that the rule of the order of member initialization. The base Duck initializes before the member m_flyrocket, but note that the base Duck is initialized with binding m_flyrocket which is not initialized yet.
As result as I run it in VS2013, this works without something wrong at run-time.
But is the code actually not safe? If not, how could I modify to a better design?
It's not safe, but it's unlikely to break unless you call m_Fly() from the base class constructor.
You can easily avoid this though, by either:
giving the base class constructor a dummy or default-constructed std::function, and re-assigning m_Fly to your bind functor in the derived class constructor
RubberDuck()
: Duck(&MuteQuack::quack, std::function<void()>())
{
m_Fly = std::bind(&FlyWithRocket::fly, std::ref(m_flyrocket));
}
making FlyWithRocket a functor itself (just rename void fly to void operator()) and passing it by value instead of keeping a private member (it will be owned by the m_Fly function object, and you can access it via std::function::target<FlyWithRocket>() if you need)
class FlyWithRocket {
public:
FlyWithRocket() : m_Energy(3) {}
void operator() () {
// ...
RubberDuck()
: Duck(&MuteQuack::quack, FlyWithRocket()) {}