It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Let me show several classes firstly:
class globalcontext
{
public:
/*partA context*/
A;
B;
c;
/*partB context*/
D;
E;
F;
.......
execute(); //a method to do something (serialize) for context above
};
class mainprocess
{
callsubprocess();
};
class subprocessA{};
class subprocessB{};
class subprocessC{};
..................
Actually, there are several backends running the main process, so the context will be sent from here or there, that's why I want to execute(serialize/unserialize).
The flow is like: mainprocess::callsubprocess() ----> choose a subprocess, so choose subprocessA----> execute partA of context from globalcontext class.
Is it possible to use factory in boost?
Maybe you are looking for a strategy pattern? Assuming that A-F encode behaviour, you could 'mixin' different behaviours or supply them as strategies:
Note: below, the separation between static/non-static member functions is a little bit arbitrary (mixins can perfectly well contain static members).
Mixins
#include <iostream>
struct NormalPartABehaviour {
void A() { std::cout << "Normal A" << std::endl; }
void B() { std::cout << "Normal B" << std::endl; }
void C() { std::cout << "Normal C" << std::endl; }
};
struct SpecialPartABehaviour {
void A() { std::cout << "Special A" << std::endl; }
void B() { std::cout << "Special B" << std::endl; }
void C() { std::cout << "Special C" << std::endl; }
};
struct NormalPartBBehaviour {
void D() { std::cout << "Normal D" << std::endl; }
void E() { std::cout << "Normal E" << std::endl; }
void F() { std::cout << "Normal F" << std::endl; }
};
template <typename PartAMixin, typename PartBMixin>
struct GlobalContext : public PartAMixin, public PartBMixin
{
};
///// test method:
template <class Context>
void test(Context globalcontext)
{
globalcontext.A();
globalcontext.B();
globalcontext.C();
globalcontext.D();
globalcontext.E();
globalcontext.F();
}
int main()
{
GlobalContext<NormalPartABehaviour, NormalPartBBehaviour> ctx1;
GlobalContext<SpecialPartABehaviour, NormalPartBBehaviour> ctx2;
std::cout << "testing ctx1: \n";
test(ctx1);
std::cout << "testing ctx2: \n";
test(ctx2);
}
Output http://liveworkspace.org/code/b6b5cfffba11df68bc70c432b030b1d5
testing ctx1:
Normal A
Normal B
Normal C
Normal D
Normal E
Normal F
testing ctx2:
Special A
Special B
Special C
Normal D
Normal E
Normal F
Strategy
#include <iostream>
struct NormalPartABehaviour {
static void A() { std::cout << "Normal A" << std::endl; }
static void B() { std::cout << "Normal B" << std::endl; }
static void C() { std::cout << "Normal C" << std::endl; }
};
struct SpecialPartABehaviour {
static void A() { std::cout << "Special A" << std::endl; }
static void B() { std::cout << "Special B" << std::endl; }
static void C() { std::cout << "Special C" << std::endl; }
};
struct NormalPartBBehaviour {
static void D() { std::cout << "Normal D" << std::endl; }
static void E() { std::cout << "Normal E" << std::endl; }
static void F() { std::cout << "Normal F" << std::endl; }
};
template <typename PartAMixin, typename PartBMixin>
struct GlobalContext
{
static void A() { PartAMixin::A(); }
static void B() { PartAMixin::B(); }
static void C() { PartAMixin::C(); }
static void D() { PartBMixin::D(); }
static void E() { PartBMixin::E(); }
static void F() { PartBMixin::F(); }
};
///// test method:
template <class Context>
void test()
{
Context::A();
Context::B();
Context::C();
Context::D();
Context::E();
Context::F();
}
int main()
{
typedef GlobalContext<NormalPartABehaviour, NormalPartBBehaviour> ctx1;
typedef GlobalContext<SpecialPartABehaviour, NormalPartBBehaviour> ctx2;
std::cout << "testing ctx1: \n";
test<ctx1>();
std::cout << "testing ctx2: \n";
test<ctx2>();
}
Output http://liveworkspace.org/code/8bca96d0e9784026c6357a30110bc5fd
testing ctx1:
Normal A
Normal B
Normal C
Normal D
Normal E
Normal F
testing ctx2:
Special A
Special B
Special C
Normal D
Normal E
Normal F
Related
Why does this give this error -
'void D::func(const D &)': cannot convert argument 1 from 'const C' to 'const D &'
How to correct this, I want to call Base's func from Derived's func but note func is a friend function?
class C
{
public:
C()
{
cout << "in C ctor" << endl;
}
friend void func(const C& abc1)
{
cout << "in C's func" << endl;
}
};
class D : public C
{
public:
D()
{
cout << "in D ctor" << endl;
}
void func(const D& abc)
{
func(static_cast<const C&>(abc));
cout << "in D's func" << endl;
}
};
int main()
{
D d;
d.func(d);
}
why does this similar e.g. work though -
https://ideone.com/eNmvng
I'm not sure what that syntaxis does with function visibility, but this works:
class C
{
public:
C()
{
cout << "in C ctor" << endl;
}
friend void func(const C& abc1);
};
void func(const C& abc1)
{
cout << "in C's func" << endl;
}
class D : public C
{
public:
D()
{
cout << "in D ctor" << endl;
}
void func(const D& abc)
{
::func(abc);
cout << "in D's func" << endl;
}
};
int main()
{
D d;
d.func(d);
}
Just for completeness sake, this works too:
class C
{
public:
C()
{
cout << "in C ctor" << endl;
}
friend void func(const C& abc1)
{
cout << "in C's func" << endl;
}
};
// Make function visible in global scope
void func(const C& abc1);
class D : public C
{
public:
D()
{
cout << "in D ctor" << endl;
}
void func(const D& abc)
{
::func(abc);
cout << "in D's func" << endl;
}
};
int main()
{
D d;
d.func(d);
}
This question already has answers here:
What is object slicing?
(18 answers)
Closed 1 year ago.
I am building up a CRTP interface and noticed some undefined behavior. So, I built up some sample code to narrow down the problem.
#include <iostream>
template <typename T>
class Base {
public:
int a() const { return static_cast<T const&>(*this).a_IMPL(); }
int b() const { return static_cast<T const&>(*this).b_IMPL(); }
int c() const { return static_cast<T const&>(*this).c_IMPL(); }
};
class A : public Base<A> {
public:
A(int a, int b, int c) : _a(a), _b(b), _c(c) {}
int a_IMPL() const { return _a; }
int b_IMPL() const { return _b; }
int c_IMPL() const { return _c; }
private:
int _a;
int _b;
int _c;
};
template <typename T>
void foo(const T& v) {
std::cout << "foo()" << std::endl;
std::cout << "a() = " << static_cast<Base<T>>(v).a() << std::endl;
std::cout << "b() = " << static_cast<Base<T>>(v).b() << std::endl;
std::cout << "c() = " << static_cast<Base<T>>(v).c() << std::endl;
}
int main() {
A v(10, 20, 30);
std::cout << "a() = " << v.a() << std::endl;
std::cout << "b() = " << v.b() << std::endl;
std::cout << "c() = " << v.c() << std::endl;
foo(v);
return 0;
}
The output of this code is:
a() = 10
b() = 20
c() = 30
foo()
a() = 134217855
b() = 0
c() = -917692416
It appears that there is some problem when casting the child class, which implements the CRTP "interface", to the interface itself. This doesn't make sense to me because the class A plainly inherits from Base so, shouldn't I be able to cast an instance of A into Base?
Thanks!
You copy and slice when you cast to Base<T>.
Cast to a const Base<T>& instead:
std::cout << "a() = " << static_cast<const Base<T>&>(v).a() << std::endl;
std::cout << "b() = " << static_cast<const Base<T>&>(v).b() << std::endl;
std::cout << "c() = " << static_cast<const Base<T>&>(v).c() << std::endl;
It turns out I was casting incorrectly to a value rather than a reference
std::cout << "a() = " << static_cast<Base<T>>(v).a() << std::endl;
should become
std::cout << "a() = " << static_cast<const Base<T>&>(v).a() << std::endl;
#include <iostream>
#include <any>
using namespace std;
class c {
public:
c() :a{ 0 } { cout << "constructor\n"; }
c(int aa) :a{ aa } { cout << "Constructor\n"; }
~c() { cout << "destructor\n"; }
int get() { return a; }
private:
int a;
};
auto main()->int
{
any a{ 5 };
cout << any_cast<int>(a) << '\n';
a.emplace<c>(3);
cout << '!' << any_cast<c>(a).get() << '\n';
//des
cout << '\n';
a.emplace<c>(9);
cout << '!' << any_cast<c>(a).get() << '\n';
//des
}
destructor called after each any_cast.
and, below code makes run-time error.
I think the cause is any_cast(C)'s work pipeline is might be like
~C() then X(C) ERROR!!C doesn't exist
any_cast really work like that?
I add blow codes and make run-time error.
class X {
public:
X() :a{ 0 } { cout << "xonstructor\n"; }
X(c& aa) :a{ aa.get() } { cout << "Xonstructor\n"; }
~X() { cout << "Xdestructor\n"; }
int get() { return a; }
private:
int a;
};
auto main()->int
{
any a{ 5 };
cout << any_cast<int>(a) << '\n';
a.emplace<c>(3);
cout << '!' << any_cast<X>(a).get() << '\n';
//runtime error after '!'
cout << '\n';
a.emplace<c>(9);
cout << '!' << any_cast<X>(a).get() << '\n';
}
You are copying a c (or X) from the one within the std::any. That copy is destroyed at the end of the expression, after having been streamed out.
any_cast does not do any conversion. It throws if you ask it for a type different to the one it stores. When you have emplaced a c and asked for an X, it throws std::bad_any_cast, because X is not c.
i have troubles with some methods after inherit.
It's hard (for me) to say where exactly problem is but i will try to expose this by example.
Minimal code:
#include <iostream>
class A
{
public:
A() {};
A(int x):val(x)
{
std::cout << "A constructor work" << std::endl;
}
int get()
{
std::cout << "Get A work" << std::endl;
return val;
}
protected:
int val;
};
class B: protected A
{
public:
B(int x) :A(x)
{
std::cout << "B constructor work" << std::endl;
test();
}
int get()
{
std::cout << "Get B work" << std::endl;
return A::get();
}
protected:
void test()
{
if (A::val == 0)
{
std::cout << "Test B work" << std::endl;
A::val = 1;
}
}
};
class C : protected A
{
public:
C() {};
C(int x) :A(x)
{
std::cout << "C constructor work" << std::endl;
test();
}
int get()
{
std::cout << "Get C work" << std::endl;
return A::get();
}
protected:
void test()
{
std::cout << "Test C work" << std::endl;
if (A::val != 0)
{
A::val += 2;
}
}
};
class D : private B, private C
{
public:
D(int x):B(x)
{
std::cout << "D constructor work" << std::endl;
C::test();
}
int get()
{
std::cout << "Get D work" << std::endl;
return B::get();
}
};
int main()
{
D d(0);
std::cout << d.get() << std::endl;
}
Output:
**A constructor work
B constructor work
Test B work
D constructor work
Test C work
Test C extra work
Get D work
Get B work
Get A work
1**
I expect val = 3 in the end, but it dont work like that.
I would be particularly grateful for your detailed reply.
Your class D contains two A objects - the one inherited by B and the one inherited by C
When you call C::test() you change the A object in C.
When you call D::get() - which calls B::get() - you inspect the value of the A object in B.
One way to get around this is by means of virtual inheritance. That is not something you want to mess with until you understand how multiple inheritance works, though.
This question already has answers here:
What is a converting constructor in C++ ? What is it for?
(3 answers)
Closed 3 years ago.
I am confused how can we pass an integer when the parameter of a function only accept a class of type enemy ( void foo(const Enemy& inKlep ).
Yet when we pass to it an int (300) it compiles. Why is this?
#include <iostream>
using namespace std;
class Enemy {
public:
Enemy() { cout << "E ctor" << endl; }
Enemy(int i) { cout << "E ctor " << i << endl; }
Enemy(const Enemy& src) {cout << "E copy ctor"<< endl;}
Enemy& operator=(const Enemy& rhs) {cout<<"E="<<endl;}
virtual ~Enemy() { cout << "E dtor" << endl; }
void hornet(int i=7) const { // Not virtual!
cout << "E::hornet " << i << endl;
}
};
class Scott : public Enemy {
public:
Scott() : Enemy(1) { cout << "S ctor" << endl; }
Scott& operator=(const Scott& rhs) {cout<<"S="<<endl;}
virtual ~Scott() { cout << "S dtor" << endl; }
void hornet(int i=7) const {
cout<<"S::hornet " << i << endl;
}
};
void foo(const Enemy& inKlep) {
Enemy theEnemy;
inKlep.hornet(2);
}
int main(int argc, char** argv) {
foo(300);
cout << "Done!" << endl; // Don't forget me!
}
In C++, it is valid code for an input parameter to implicitly construct an object if the function expects an object that can be constructed from that parameter. So, for example:
struct CustomInt {
int val;
CustomInt() : CustomInt(0) {}
CustomInt(int value) : val(value) {}
};
void func(CustomInt obj) {
std::cout << obj.val << std::endl;
}
int main() {
func(5); //Valid; will print '5' to the console
}
If you don't want to allow this, you need to add the keyword explicit to the constructor to prevent this.
struct CustomInt {
int val;
CustomInt() : CustomInt(0) {}
explicit CustomInt(int value) : val(value) {}
};
void func(CustomInt obj) {
std::cout << obj.val << std::endl;
}
int main() {
//func(5); //Invalid; will cause a compile-time error
func(CustomInt(5)); //Valid; will print '5' to the console
}