C++ design pattern - member-only class - c++

I want a class that can only be instantiated as a member of another class.
Id est:
class A
{
public:
A() :
member_()
{};
void letBSayHi() { member_.sayHi(); }
private:
B member_;
};
class B
{
public:
void sayHi() { printf("hola!"); }
};
thus:
A alpha; // valid
alpha.letBSayHi(); // # hola!
B beta; // invalid
beta.sayHi(); // impossible
The singleton pattern obviously wouldn't work, as I want one instance of class B for every instance of class A. But any instantiation of class B other than as a class A-member should be prohibited.

Make B a private nested class of A:
class A {
public:
void letBSayHi() { member_.sayHi(); }
private:
class B {
public:
void sayHi() { std::cout << "hola!"; }
};
B member_;
};
Addendum re: comment: The implementation can be separated from the declaration like this:
Header:
class A {
public:
void letBSayHi();
private:
class B {
public:
void sayHi();
};
B member_;
};
Source file:
void A::letBSayHi() { member_.sayHi(); }
void A::B::sayHi() { std::cout << "hola!\n"; }
// ^^^^-- interesting part here

Well, if you want to include, why not?
class A {
#include "B.hpp"
...
};

Related

Overriding protected field members in C++ not working?

In the following, I expected class Child's protected field member _AorB to be of type B, and not A, but reality shows otherwise.
What am I mis-understanding, and how can I adjust the code for the desired behavior?
class A{
public:
void doit(){
std::cout<<" this is A!"<<std::endl;
}
};
class B{
public:
void doit(){
std::cout<<" this is B!"<<std::endl;
}
};
class Parent{
public:
void doit(){
_AorB.doit();
}
protected:
A _AorB;
};
class Child: public virtual Parent{
protected:
B _AorB;
};
int main()
{
cout<<"Hello World";
auto c = Child();
c.doit(); // I expected this to print "This is B" because c is Child(), and Child class's _AorB is of type B.
return 0;
}
You can make such changes:
template <typename AorB>
class Parent{
public:
void doit(){
_AorB.doit();
}
protected:
AorB _AorB;
};
class Child: public virtual Parent<B> {
}
Also take a look at What are the rules about using an underscore in a C++ identifier?
Reserved in any scope, including for use as implementation macros:
identifiers beginning with an underscore followed immediately by an uppercase letter
273K's answer is excellent.
Depending on what kind of problem you are trying to solve and how the data is held in the hierarchy, you could use a std::variant<A, B> to allow "flippy" behavior based on the type, and access that member variable through a virtual getter member function.
#include <iostream>
#include <variant>
class A {
public:
void doit() {
std::cout << " this is A!\n";
}
};
class B {
public:
void doit() {
std::cout << " this is B!\n";
}
};
class Parent {
public:
virtual ~Parent() = default;
void doit() {
auto ab = get_AorB();
std::visit([](auto arg) { arg.doit(); }, ab);
}
virtual auto get_AorB() -> std::variant<A, B> {
return _a;
}
protected:
A _a;
};
class Child : public virtual Parent {
protected:
B _b;
auto get_AorB() -> std::variant<A, B> override {
return _b;
}
};
int main() {
std::cout << "Hello World";
auto c = Child();
c.doit(); // "this is B!"
}

How to call superclass method in multiple-inheritance?

I have a class C that inherits both from Ai and B. A and B are unrelated. This is all best explained with the code below. In main(), I have a variable a defined as std::unique_ptr<A>, but initialized with C. I cannot change this definition.
My question is, given a defined like this, how can I call functions defined in B or C or Ai correctly?
#include <memory>
class A
{
public:
void fun_a() {}
};
class B
{
public:
void fun_b() {}
};
class Ai : public A
{
public:
void fun_ai() {}
};
class C: public Ai, public B
{
public:
void fun_c() {}
};
int main()
{
// I cannot change the following definition:
std::unique_ptr<A> a = std::make_unique<C>();
a->fun_a();
//a->fun_b(); // How ?
//a->fun_c(); // How ?
//a->fun_ai(); // How ?
return 0;
}
You can static_cast to C*:
static_cast<C*>(a.get())->fun_b();
static_cast<C*>(a.get())->fun_c();
static_cast<C*>(a.get())->fun_ai();
or you could make it polymorphic:
class A {
public:
virtual ~A() = default;
void fun_a() { std::cout << "fun_a\n"; }
};
and then dynamic_cast:
dynamic_cast<B*>(a.get())->fun_b();
dynamic_cast<C*>(a.get())->fun_c();
dynamic_cast<Ai*>(a.get())->fun_ai();
Note: dynamic_casts to pointer types may fail and return nullptr so, if there's any doubt, check the return value.
Demo

multiple inheritance for function only - without virtual and CRTP

How to do multiple inheritance just for function?
must share data of the base class
no virtual function (assume that vtable is expensive)
avoid virtual inheritance
implementation must be able to reside in .cpp
c++14 is allowed
Here are similar questions :-
Multiple inheritance in diamond shape with functions only - use virtual inheritance. Virtual inheritance is generally bad and expensive.
multiple inheritance without virtual inheritance - focuses on syntax and compiling rather than programming technique.
Multilevel inheritance in c++ (CRTP) , CRTP and multilevel inheritance , Eliminate redundancy with CRTP and multiple inheritance (C++03) and Using CRTP with virtual inheritance - implementation must be in header
Here is a sample code (coliru demo) :-
class O{
protected: int database=0;
};
class A : public O{
public: void print(){
std::cout<<database<<std::endl;
}
};
class B : public O{
public: void set(int s){
database=s+1;
}
};
class AB : public O{
public: void print(){//duplicate
std::cout<<database<<std::endl;
}
public: void set(int s){//duplicate
database=s+1;
}
};
//AB ab; ab.set(1); ab.print(); // would print 2
Here is my attempt (wandbox demo). I abuse CRTP :( :-
class O{
public: int database=0;
};
template<class T>class OA{
public: void print(){
std::cout<<static_cast<T*>(this)->database<<std::endl;
}
};
template<class T>class OB{
public: void set(int s){
static_cast<T*>(this)->database=s+1;
}
};
class A :public O,public OA<A>{};
class B :public O,public OB<B>{};
class AB :public O,public OA<AB>,public OB<AB>{};
It works, but it looks inelegant.
Furthermore, implementation must be in header (because OA and OB are template classes).
Are there better approaches? Or is this the way to go?
Sorry if it is too newbie question or already asked. I am a C++ beginner.
Edit
Give extended example of using please.
In ECS, it would be useful in some cases :-
class O{
protected: EntityHandle e;
};
class ViewAsPhysic : public O{ //A
public: void setTransform(Transformation t){
Ptr<PhysicTransformComponent> g=e;
g->transform=t;
}
};
class ViewAsLight : public O{ //B
public: void setBrightness(int t){
Ptr<LightComponent> g=e;
g->clan=t;
}
};
class ViewAsLightBlock : public O{ //AB
//both functions
};
The problem here is that the database field is member of class O. So without virtual inheritance, A and B will have each their own copy of database. So you must find a way to force A and B to share same value. You could for example use a reference field initialized in a protected constructor:
#include <iostream>
class O{
int _db;
protected: int &database;
O(): database(_db) {};
O(int &db): database(db) {};
};
class A : public O{
public: void print(){
std::cout<<database<<std::endl;
}
A() {} // public default ctor
protected: A(int& db): O(db) {}; // protectect ctor
};
class B : public O{
public: void set(int s){
database=s+1;
}
B() {} // public default ctor
protected: B(int& db): O(db) {}; // protectect ctor
};
class AB : public A, public B {
int _db2;
public: AB(): A(_db2), B(_db2) {}; // initialize both references to same private var
};
int main() {
AB ab;
ab.set(1);
ab.print();
return 0;
}
displays as expected:
2
Above code uses no virtual inheritance, no virtual function and no templates, so method can safely implemented in cpp files. The class AB actually uses methods from its both parents and has still a coherent view on its underlying data. In fact it simulates an explicit virtual inheritance by building the common data in the most derived class and injecting in through protected constructors in its parents.
Something like this?
must share data of the base class - check
no virtual function (assume that vtable is expensive) - check
avoid virtual inheritance - check
implementation must be able to reside in .cpp- check
c++14 is allowed - check. c++11 used.
#include <iostream>
class O {
protected:
int database = 0;
};
/*
* the concept of implementing print for a base class
*/
template<class...Bases>
struct implements_print : Bases... {
void print() const {
std::cout << this->database << std::endl;
}
};
/*
* The concept of implementing set for a base class
*/
template<class...Bases>
struct implements_set : Bases... {
void set() {
++this->database;
}
};
struct B : implements_set<O> {
};
struct A : implements_print<O> {
};
struct AB : implements_set<implements_print<O>> {
};
int main() {
A a;
a.print();
B b;
b.set();
AB ab;
ab.set();
ab.print();
}
Another way, using composition and an access class to provide access to the protected member. This example shows how to defer the work on database to another compilation unit:
#include <iostream>
/*
* this stuff in cpp
*/
namespace implementation
{
void print(const int& database) {
std::cout << database << std::endl;
}
void set(int& database) {
++database;
}
}
/*
* this stuff in header
*/
struct OAccess;
class O {
private:
int database = 0;
friend OAccess;
};
struct OAccess {
template<class Host>
constexpr decltype(auto) database(Host &host) const { return (host.database); } // note: () makes reference
template<class Host>
constexpr decltype(auto) database(Host const &host) const { return (host.database); } // note: () makes reference
};
/*
* the concept of implementing print for a derived class
*/
template<class Host>
struct implements_print {
void print() const {
OAccess access;
implementation::print(access.database(self()));
}
private:
decltype(auto) self() const { return static_cast<Host const &>(*this); }
};
/*
* The concept of implementing set for a derived class
*/
template<class Host>
struct implements_set {
void set() {
OAccess access;
implementation::set(access.database(self()));
}
private:
decltype(auto) self() { return static_cast<Host &>(*this); }
};
template<template<class> class...Impls>
struct OImpl : Impls<OImpl<Impls...>> ..., O {
};
using B = OImpl<implements_set>;
using A = OImpl<implements_print>;
using AB = OImpl<implements_print, implements_set>;
int main() {
A a;
a.print();
B b;
b.set();
AB ab;
ab.set();
ab.print();
}
We start with defining the concepts of things that can print and things that can be set:
namespace util {
template<class Base, class Derived, class R=void>
using if_base = std::enable_if_t< std::is_base_of< std::decay_t<Base>, std::decay_t<Derived>>::value, R >;
struct stub {};
}
namespace concepts {
template<class Token>
void do_print(Token, util::stub const&)=delete;
template<class Token>
void do_set(Token, util::stub&, int)=delete;
struct has_print {
struct token { friend struct has_print; private: token(int){} };
template<class T>
friend util::if_base<has_print, T> print(T const& t) {
do_print(get_token(), t);
}
private: static token get_token() { return 0; }
};
struct has_set {
struct token { friend struct has_set; private: token(int){} };
template<class T>
friend util::if_base<has_set, T> set(T& t, int x) {
do_set(get_token(),t, x);
}
private: static token get_token() { return 0; }
};
}
We then declare O and the operations you can support on it:
namespace DB {
class O;
void do_print(::concepts::has_print::token, O const& o);
void do_set(::concepts::has_set::token, O& o, int);
class O{
protected: int database=0;
friend void do_print(::concepts::has_print::token, O const&);
friend void do_set(::concepts::has_set::token, O&, int);
};
class A : public O, public concepts::has_print {
};
class B : public O, public concepts::has_set {
};
class AB : public O, public concepts::has_print, concepts::has_set {
};
}
void DB::do_print(::concepts::has_print::token, O const& o ) { std::cout << o.database << std::endl; }
void DB::do_set(::concepts::has_set::token, O& o, int x) { o.database = x+1; }
The hard part of this is the access control.
I ensure it isn't possible to call do_set except through has_set::set.
That is what all those tokens are about. You can strip them out and their overhead if you are willing to just say "don't call the do_ functions" (and maybe give them another name, like private_impl_set).
Live example.
To start discussion.
class O
{
// no virtual destructor. So cant use polymorphic deletion
// like :
// O *o = new AB;
// delete o;
protected: int database=0;
};
class A : virtual public O{
public: void print(){
std::cout<<database<<std::endl;
}
};
class B : virtual public O{
public: void set(int s){
database=s+1;
}
};
class AB : protected A, protected B{}; // no vtable
void foo() {
AB ab;
ab.print(); // won't perform virtual call.
}

Cannot define nested class member function within derived class

I have a Base class composed of another class (let's call it Component). If I inherit from the Base class, is it possible to add functionality to the Component class (assumming you can't modify the Base code)? I basically want a 'Derived::Component::foo' function.
#include <iostream>
class Base
{
public:
void Print() { std::cout << c.data; }
class Component
{
public:
int data;
};
Component c;
};
class Derived : public Base
{
private:
void Component::foo(int value)
{
this->data = value;
}
public:
void bar(int value)
{
this->c.foo(value);
}
};
int main() {
Derived d;
d.bar(4);
d.Print();
}
This code gives the following error under G++ 4.8 on Ubuntu:
error: cannot define member function ‘Base::Component::foo’ within ‘Derived’
[..] add functionality [..] (assumming you can't modify the Base code) [..]
Depending on how the actual base class in question looks like, you could try to get by with simple subclassing of the Component:
/* using struct to have public accessibility */
struct Base {
struct Component {
int data;
virtual ~Component() {} // ABSOLUTELY NECESSARY
};
std::unique_ptr<Component> component; // ABSOLUTELY NECESSARY
void print(void) {
std::cout << component->data << endl;
}
};
/* The decorated component, with the additional functionality */
struct DecoratedComponent : public Base::Component {
void set(int d) {
data = d;
}
};
Then, assuming there's someway to set the component, you need to pass in your decorated component (note: If there's state to be preserved, you could also wrap an Component instance in your decorated component class, making this a real usage of the Decorator Pattern):
Base the_base;
auto the_component = std::make_unique<DecoratedComponent>();
// Inject the decorated component
the_base.component = the_component;
the_component.set(42);
the_base.print(); // 42
This will only work if the base uses either a reference or some sort of pointer to store/access it's component. Additionally, if the base is managing the lifetime of the component, the Component must have a virtual destructor.
You need to declare the foo function in the Component class. And then define it inside the Component itself:
#include <iostream>
class Base
{
public:
void Print() { std::cout << c.data; }
class Component
{
public:
int data;
void foo( int value )
{
data = value;
}
};
Component c;
};
class Derived : public Base
{
private:
public:
void bar(int value)
{
c.foo(value);
}
};
int main() {
Derived d;
d.bar(4);
d.Print();
}
Or outside of all of the classes:
#include <iostream>
class Base
{
public:
void Print() { std::cout << c.data; }
class Component
{
public:
int data;
void foo( int value );
};
Component c;
};
void Base::Component::foo(int value)
{
data = value;
}
class Derived : public Base
{
private:
public:
void bar(int value)
{
c.foo(value);
}
};
int main() {
Derived d;
d.bar(4);
d.Print();
}

Call a method from A class in constructor of other class

I want to call a method from A class in constructor of other class
I googled, but did not find any answer
For example, I have :
class A{
void doWork();
}
class B{
B(){
//here i want to have doWork method
}
}
You told us not enough to choose proper solution. Everything depends on what you are trying to achieve. A few solutions:
a) Mark A method as static.
class A
{
public:
static void DoSth()
{
// Cannot access non-static A members here!
}
};
class B
{
public:
B()
{
A::DoSth();
}
};
b) You can instantiate A in place
class A
{
public:
void DoSth()
{
// Do something
}
};
class B
{
public:
B()
{
A a;
a.DoSth();
}
};
c) You can put A's instance into B:
// A remains as in b)
class B
{
private:
A a;
// or: A * a;
public:
B()
{
a.DoSth();
// or: a = new A; a->DoSth();
// Remember to free a somewhere
// (probably in destructor)
}
}
d) You may derive B from A:
class A
{
protected:
void DoSth()
{
}
};
class B : public A
{
public:
B()
{
DoSth();
}
};
e) You can forget about A class and make DoSth a function:
void DoSth()
{
// ...
}
class B
{
public:
B()
{
DoSth();
}
}
Since you provided not enough data, you have to choose solution on your own.
In order for that to work you'd need to subclass it.
So it'd be like this:
class A {
doWork();
}
class B : A {
B(){
doWork();
}
}
You could also do it like so going for a HAS-A rather than IS-A relationship:
class A {
doWork();
}
class B {
A myA;
B(){
myA.doWork();
}
}
Without knowing more of what you are doing I'd go with the top (IS-A) solution which is what I think you are trying to do.
Or
class A
{
public:
static void doWork();
};
class B
{
B(void)
{
A::doWork();
}
};
?
PS: Here B::B() will be private