Strange initialization behavior in C ++

I have two classes Baseand Derived:

class Base{
public:
    Base(int = 0);
    Base(Base&);
    Base& operator=(const Base&);
protected:
    int protectedData;
private:
    int baseData;
};

/////////////DERIVED CLASS
class Derived: public Base{
public:
    Derived(int = 0);
    Derived(Derived&);
    Derived(Base&);
    Derived& operator=(const Derived&);
private:
    int derivedData;
};

implementation of functions

///////////BASE FUNCTIONS
Base::Base(int value): protectedData(value), baseData(value)
{
    cout << "base C'tor" << endl;
}


Base::Base(Base& base)
{
    baseData = base.baseData;
    protectedData = base.protectedData;
    cout << "base Copy C'tor" << endl;
}

Base& Base::operator=(const Base& base)
{
    if(this == &base) return *this;
    baseData = base.baseData;
    protectedData = base.protectedData;
    cout << "Base::operator=" << endl;
    return *this;
}

///////////DERIVED FUNCTIONS

Derived::Derived(int value): Base(value), derivedData(value)
{
    cout << "derived C'tor" << endl;
}

Derived::Derived(Derived& derived)
    : Base(derived)
{
    derivedData = derived.derivedData;
    cout << "derived Copy C'tor" << endl;
}

Derived::Derived(Base& base)
    : Base(base), derivedData(0)
{
    cout << " Derived(Base&) is called " << endl;
}

Derived& Derived::operator=(const Derived& derived)
{
    if(this == &derived) return *this;

    derivedData = derived.derivedData;
    cout << "Derived::operator=" << endl;
    return *this;
}

In my main:

Base base(1);
Derived derived1 = base;

the compiler gives me an error:

..\main.cpp:16: error: no matching function for call to `Derived::Derived(Derived)'
..\base.h:34: note: candidates are: Derived::Derived(Base&)
..\base.h:33: note:                 Derived::Derived(Derived&)
..\base.h:32: note:                 Derived::Derived(int)
..\main.cpp:16: error:   initializing temporary from result of `Derived::Derived(Base&)'

but when I have it mostly:

Base base(1);
Derived derived1(base);

works great. Why?

EDITED

so good thanks to everyone, I checked it with const and everything works fine, BUTI also check all the calls and in both cases I get:

base C'tor
base Copy C'tor
Derived(Base&)

my question is why? You said that I really call: Derived(Derived(Base&))therefore I must have

base C'tor
base Copy C'tor
Derived(Base&)
Derived copy c'tor //<-note, why this one is missing?
+3
source share
5 answers

Change these constructors

Base(Base&);
Derived(Derived&);
Derived(Base&);

To take const links:

Base(const Base&);
Derived(const Derived&);
Derived(const Base&);

The former cannot take temporary values; the latter can. The compiler wants to convert

Derived derived1 = base;

at

Derived derived1(Derived(base));

, Derived (base) , Derived, Derived-.

Edit:

, , , cout - . elision , (, ). Wikipedia. g++, -no-elide-constructors, .

, litb . !

+7

const ( ), . :

Derived derived1 = base;

rvalue ( ) Derived Derived:: Derived (Base &), Derived:: Derived (Derived &), r .

+5

, , :

Derived& Derived::operator=(const Base& base);

, !

, - MyClass (const MyClass & instance), const .

HTH

+1

: 1 = ; , "" "Base", .

, , , . , . , , .

. , Derived (Base &); , .

0

, , , ,

0

Source: https://habr.com/ru/post/1767755/


All Articles