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);
}
Related
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
}
I have problem with understanding order of execution in virtual void/polymorphism based program.
As far as I understand what happens in other outputs, I have no idea why those commands:
a->b();
d->b();
d->a();
((G*)d) -> a();
give following outputs:
Nieznany
Nieznany
Gniewosz
Could anyone please explain me why those 3 methods print results as above?
#include <iostream>
using namespace std;
class C { public:
C() {cout << "Buduje A";}
void a() {cout << "Nauczyciel" << endl;}
virtual ~C() {cout << "~D" << endl;}
virtual void b() {cout << "Nieznany" << endl; }; };
class G {
int e; public:
G() {cout << "Buduje G ";}
void a() {cout << "Gniewosz " << endl;}
~G() {cout << "~C " << endl; }
void b() {cout << "Draka" << endl;}; };
class A :public C {
int o;
int a;
public:
A() {cout << "Buduje C ";}
~A() {cout << "~F " << endl;} };
class D :public A {
float f; public:
D() {cout << "Buduje D";}
virtual void a() {cout << "Pośrednik" << endl;}
~D() {cout << "~E" << endl;} };
class B :public D {
short s;
int b; public:
B() {cout << "Buduje E ";}
~B() {cout << "~G" << endl;} };
class E :public B {
E() {cout << "Buduje B";}
~E() {cout << "~I" << endl;} };
class F :public G, public D { public:
F() {cout << "Buduje F ";}
void a() {cout << "Nieznany " << endl;}
void b() {}
~F() {cout << "~H" << endl;} };
void nic() {cout << endl;}
int main() {
C*a = new B();
nic();
a->b();
D*d = new F;
nic();
d->b();
d->a();
((G*)d) -> a();
delete d;
delete a;
return 0; }
Im kinda new to C++.
I have an assignment where I should implement c class' default ctor and cctor so that theyll print "c::ctor" and "c::cctor" respectively.
I have no idea of how to deal with this, help would be appreciated.
#include <iostream>
#include <string>
using namespace std;
class a {
public:
a(const char* sname)
: _sname(sname) {
cout << "a::ctor" << endl;
}
a(const a& s) { cout << "a::copy ctor" << endl; }
virtual ~a() { cout << "a::dtor " << endl; }
void f1() { cout << "a::f1()" << endl; f2(); }
virtual void f2() = 0;
private:
string _sname;
};
class b1 : virtual public a {
public:
b1(const char* saname, const char* ssname)
: _sname1(saname), a(ssname) {
}
b1(const b1& b1) : a(b1) { cout << "b1 :: copy ctor << endl"; }
~b1() { cout << "b1::dtor" << endl; }
virtual void f1() { cout << "b1::f1()" << endl; }
virtual void f2() { cout << "b1::f2()" << endl; }
virtual void f3() { cout << "b1::f3()" << endl; }
private:
string _sname1;
};
class b2 : virtual public a {
public:
b2(const char* saname, const char* ssname)
: _sname2(saname), a(ssname) {
cout << "b2::ctor" << endl;
}
b2(const b2& b2) : a(b2) { cout << "b2::copy ctor" << endl; }
~b2() { cout << "b2::dtor" << endl; }
virtual void f3() { f1(); cout << "b2::f3()" << endl; }
private:
string _sname2;
};
class c : public b1, public b2 {
public:
c();
c(const c& c);
~c() { cout << "c::dtor" << endl; }
virtual void f1() { a::f1(); cout << "c::f1()" << endl; }
void f3() { cout << "c::f3()" << endl; }
};
In case of virtual inheritance, things are more complicated for the constructors and destructors. The constructors and the destructors of the virtual base class a should also be called in the c class since the compiler cannot choose between b1 or b2 to build the (unique) a part in the c object. For the destructor, the compilers handles things to call the destructor of b1, the destructor of b2 and the destructor of a.
So you should implement
class c : public b1, public b2 {
public:
c() : b1("", ""), b2("", ""), a("") {}
c(const c& src) : b1(src), b2(src), a(src) {}
};
In general, you should try to avoid virtual inheritance when not necessary. But it is a good exercise to understand how it works.
I have an explicit function that takes a reference to the base type of a class. What is the proper way to pass that in?
I am currently doing a static cast:
#include <iostream>
using namespace std;
struct Base
{
Base() { cout << "Base Constructor" << endl; }
Base(Base const& c) { cout << "Base-Base Constructor" << endl; }
};
struct Derived : public Base
{
Derived() { cout << "Derived Constructor" << endl; }
explicit Derived(Base const& c) { cout << "Derived-Base Constructor" << endl; }
Derived(Derived const& c) { cout << "Derived-Derived Constructor" << endl; }
};
int main()
{
Base B;
cout << "\n";
Derived D;
cout << "\n";
Base* test1 = new Derived(D);
cout << "\n";
Base* test3 = new Derived(static_cast<Base>(D));
cout << "\n";
Base* test2 = new Derived(B);
cout << "\n";
return 0;
}
but that calls the copy constructor of the base class.
I could pass *static_cast<Base*>(&D), but that seems a bit hackish. I feel like I am just overlooking a simple way to do this. Thanks.
Use this:
static_cast<Base&>(D)
Or this:
static_cast<const Base&>(D)
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