Constructor taking Base& is not called

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
9
down vote

favorite












I'm working on a simple program for Boolean algebra, but the double negation does not work as expected.



I have the following classes:



Operator:



#ifndef OPERATOR_H
#define OPERATOR_H

class Operator
public:
virtual int getArity(void) const = 0;
virtual bool calc(void) const = 0;
;

#endif // OPERATOR_H


False:



#ifndef FALSE_H
#define FALSE_H

#include "operator.h"

class False : public Operator
public:
int getArity() const
return 0;


bool calc(void) const
return false;

;

#endif // FALSE_H


Not:



#ifndef NOT_H
#define NOT_H

#include "operator.h"

class Not : public Operator
public:
Not(Operator& child) : m_child(child)
std::cout << "not constructor called" << std::endl;


int getArity(void) const
return 1;


bool calc(void) const
return !m_child.calc();


private:
Operator& m_child;
;

#endif // NOT_H


My main.cpp:



#include <iostream>
#include "operator.h"
#include "not.h"
#include "false.h"

using namespace std;

int main(int argc, char *argv)

False f;
Not n = Not(f);
Not d = Not(n);

cout << "n.calc(): " << n.calc() <<endl;
cout << "d.calc(): " << d.calc() <<endl;
return 0;



Since d = Not(Not(False())) I expect it to be false.



The output is:



not constructor called
n.calc(): 1
d.calc(): 1 <== should be 0


Why is the constructor of the class Not not called with an object of type Not as child?










share|improve this question









New contributor




Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • The best way I've found to figure out what happens in cases like this is to implement every constructor and add some debug statements, explicitly logging every constructor called. It can be very informative.
    – Andrew Henle
    5 hours ago











  • Aside: I would highlight this en.cppreference.com/w/cpp/language/operator_alternative and beg you to reconsider what you're doing. (And at last checking, false is not an operator, but a binary value)
    – UKMonkey
    5 hours ago











  • note that T x = T(a); is defined as being the same as T x(a);, since C++17.
    – M.M
    5 hours ago






  • 4




    "class False : public Operator" Reminds me of a "famous" german author who managed to let his class Wurstbrot inherit from Wurst and Brot which in turn inherit Supermarkt ...
    – J. Doe
    4 hours ago






  • 2




    @UKMonkey "false" is usually the name of a boolean value, but it is also the name of a nullary operator (meaning it doesn't take any argument) that returns that boolean value.
    – Nelfeal
    4 hours ago














up vote
9
down vote

favorite












I'm working on a simple program for Boolean algebra, but the double negation does not work as expected.



I have the following classes:



Operator:



#ifndef OPERATOR_H
#define OPERATOR_H

class Operator
public:
virtual int getArity(void) const = 0;
virtual bool calc(void) const = 0;
;

#endif // OPERATOR_H


False:



#ifndef FALSE_H
#define FALSE_H

#include "operator.h"

class False : public Operator
public:
int getArity() const
return 0;


bool calc(void) const
return false;

;

#endif // FALSE_H


Not:



#ifndef NOT_H
#define NOT_H

#include "operator.h"

class Not : public Operator
public:
Not(Operator& child) : m_child(child)
std::cout << "not constructor called" << std::endl;


int getArity(void) const
return 1;


bool calc(void) const
return !m_child.calc();


private:
Operator& m_child;
;

#endif // NOT_H


My main.cpp:



#include <iostream>
#include "operator.h"
#include "not.h"
#include "false.h"

using namespace std;

int main(int argc, char *argv)

False f;
Not n = Not(f);
Not d = Not(n);

cout << "n.calc(): " << n.calc() <<endl;
cout << "d.calc(): " << d.calc() <<endl;
return 0;



Since d = Not(Not(False())) I expect it to be false.



The output is:



not constructor called
n.calc(): 1
d.calc(): 1 <== should be 0


Why is the constructor of the class Not not called with an object of type Not as child?










share|improve this question









New contributor




Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • The best way I've found to figure out what happens in cases like this is to implement every constructor and add some debug statements, explicitly logging every constructor called. It can be very informative.
    – Andrew Henle
    5 hours ago











  • Aside: I would highlight this en.cppreference.com/w/cpp/language/operator_alternative and beg you to reconsider what you're doing. (And at last checking, false is not an operator, but a binary value)
    – UKMonkey
    5 hours ago











  • note that T x = T(a); is defined as being the same as T x(a);, since C++17.
    – M.M
    5 hours ago






  • 4




    "class False : public Operator" Reminds me of a "famous" german author who managed to let his class Wurstbrot inherit from Wurst and Brot which in turn inherit Supermarkt ...
    – J. Doe
    4 hours ago






  • 2




    @UKMonkey "false" is usually the name of a boolean value, but it is also the name of a nullary operator (meaning it doesn't take any argument) that returns that boolean value.
    – Nelfeal
    4 hours ago












up vote
9
down vote

favorite









up vote
9
down vote

favorite











I'm working on a simple program for Boolean algebra, but the double negation does not work as expected.



I have the following classes:



Operator:



#ifndef OPERATOR_H
#define OPERATOR_H

class Operator
public:
virtual int getArity(void) const = 0;
virtual bool calc(void) const = 0;
;

#endif // OPERATOR_H


False:



#ifndef FALSE_H
#define FALSE_H

#include "operator.h"

class False : public Operator
public:
int getArity() const
return 0;


bool calc(void) const
return false;

;

#endif // FALSE_H


Not:



#ifndef NOT_H
#define NOT_H

#include "operator.h"

class Not : public Operator
public:
Not(Operator& child) : m_child(child)
std::cout << "not constructor called" << std::endl;


int getArity(void) const
return 1;


bool calc(void) const
return !m_child.calc();


private:
Operator& m_child;
;

#endif // NOT_H


My main.cpp:



#include <iostream>
#include "operator.h"
#include "not.h"
#include "false.h"

using namespace std;

int main(int argc, char *argv)

False f;
Not n = Not(f);
Not d = Not(n);

cout << "n.calc(): " << n.calc() <<endl;
cout << "d.calc(): " << d.calc() <<endl;
return 0;



Since d = Not(Not(False())) I expect it to be false.



The output is:



not constructor called
n.calc(): 1
d.calc(): 1 <== should be 0


Why is the constructor of the class Not not called with an object of type Not as child?










share|improve this question









New contributor




Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I'm working on a simple program for Boolean algebra, but the double negation does not work as expected.



I have the following classes:



Operator:



#ifndef OPERATOR_H
#define OPERATOR_H

class Operator
public:
virtual int getArity(void) const = 0;
virtual bool calc(void) const = 0;
;

#endif // OPERATOR_H


False:



#ifndef FALSE_H
#define FALSE_H

#include "operator.h"

class False : public Operator
public:
int getArity() const
return 0;


bool calc(void) const
return false;

;

#endif // FALSE_H


Not:



#ifndef NOT_H
#define NOT_H

#include "operator.h"

class Not : public Operator
public:
Not(Operator& child) : m_child(child)
std::cout << "not constructor called" << std::endl;


int getArity(void) const
return 1;


bool calc(void) const
return !m_child.calc();


private:
Operator& m_child;
;

#endif // NOT_H


My main.cpp:



#include <iostream>
#include "operator.h"
#include "not.h"
#include "false.h"

using namespace std;

int main(int argc, char *argv)

False f;
Not n = Not(f);
Not d = Not(n);

cout << "n.calc(): " << n.calc() <<endl;
cout << "d.calc(): " << d.calc() <<endl;
return 0;



Since d = Not(Not(False())) I expect it to be false.



The output is:



not constructor called
n.calc(): 1
d.calc(): 1 <== should be 0


Why is the constructor of the class Not not called with an object of type Not as child?







c++ inheritance constructor






share|improve this question









New contributor




Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 11 mins ago









Peter Mortensen

13.2k1983111




13.2k1983111






New contributor




Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 5 hours ago









Core

543




543




New contributor




Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Core is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • The best way I've found to figure out what happens in cases like this is to implement every constructor and add some debug statements, explicitly logging every constructor called. It can be very informative.
    – Andrew Henle
    5 hours ago











  • Aside: I would highlight this en.cppreference.com/w/cpp/language/operator_alternative and beg you to reconsider what you're doing. (And at last checking, false is not an operator, but a binary value)
    – UKMonkey
    5 hours ago











  • note that T x = T(a); is defined as being the same as T x(a);, since C++17.
    – M.M
    5 hours ago






  • 4




    "class False : public Operator" Reminds me of a "famous" german author who managed to let his class Wurstbrot inherit from Wurst and Brot which in turn inherit Supermarkt ...
    – J. Doe
    4 hours ago






  • 2




    @UKMonkey "false" is usually the name of a boolean value, but it is also the name of a nullary operator (meaning it doesn't take any argument) that returns that boolean value.
    – Nelfeal
    4 hours ago
















  • The best way I've found to figure out what happens in cases like this is to implement every constructor and add some debug statements, explicitly logging every constructor called. It can be very informative.
    – Andrew Henle
    5 hours ago











  • Aside: I would highlight this en.cppreference.com/w/cpp/language/operator_alternative and beg you to reconsider what you're doing. (And at last checking, false is not an operator, but a binary value)
    – UKMonkey
    5 hours ago











  • note that T x = T(a); is defined as being the same as T x(a);, since C++17.
    – M.M
    5 hours ago






  • 4




    "class False : public Operator" Reminds me of a "famous" german author who managed to let his class Wurstbrot inherit from Wurst and Brot which in turn inherit Supermarkt ...
    – J. Doe
    4 hours ago






  • 2




    @UKMonkey "false" is usually the name of a boolean value, but it is also the name of a nullary operator (meaning it doesn't take any argument) that returns that boolean value.
    – Nelfeal
    4 hours ago















The best way I've found to figure out what happens in cases like this is to implement every constructor and add some debug statements, explicitly logging every constructor called. It can be very informative.
– Andrew Henle
5 hours ago





The best way I've found to figure out what happens in cases like this is to implement every constructor and add some debug statements, explicitly logging every constructor called. It can be very informative.
– Andrew Henle
5 hours ago













Aside: I would highlight this en.cppreference.com/w/cpp/language/operator_alternative and beg you to reconsider what you're doing. (And at last checking, false is not an operator, but a binary value)
– UKMonkey
5 hours ago





Aside: I would highlight this en.cppreference.com/w/cpp/language/operator_alternative and beg you to reconsider what you're doing. (And at last checking, false is not an operator, but a binary value)
– UKMonkey
5 hours ago













note that T x = T(a); is defined as being the same as T x(a);, since C++17.
– M.M
5 hours ago




note that T x = T(a); is defined as being the same as T x(a);, since C++17.
– M.M
5 hours ago




4




4




"class False : public Operator" Reminds me of a "famous" german author who managed to let his class Wurstbrot inherit from Wurst and Brot which in turn inherit Supermarkt ...
– J. Doe
4 hours ago




"class False : public Operator" Reminds me of a "famous" german author who managed to let his class Wurstbrot inherit from Wurst and Brot which in turn inherit Supermarkt ...
– J. Doe
4 hours ago




2




2




@UKMonkey "false" is usually the name of a boolean value, but it is also the name of a nullary operator (meaning it doesn't take any argument) that returns that boolean value.
– Nelfeal
4 hours ago




@UKMonkey "false" is usually the name of a boolean value, but it is also the name of a nullary operator (meaning it doesn't take any argument) that returns that boolean value.
– Nelfeal
4 hours ago












1 Answer
1






active

oldest

votes

















up vote
18
down vote



accepted










Not d = Not(n); invokes the copy constructor of Not, because the argument is also of type Not. The copy constructor's signature matches better and it's therefore selected.






share|improve this answer
















  • 3




    More detail: Not(Operator& child) is not a copy-constructor, despite the fact that it can be called with an argument of the same type. The implicitly-defined copy-constructor also exists.
    – M.M
    5 hours ago






  • 3




    As a possible solution, you could take Operator* child, or pass the value with static_const<Operator&>. To avoid the silent copy, you can delete the copy-constructor and use uniform initialization syntax.
    – José Manuel
    4 hours ago










Your Answer





StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);






Core is a new contributor. Be nice, and check out our Code of Conduct.









 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53046123%2fconstructor-taking-base-is-not-called%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
18
down vote



accepted










Not d = Not(n); invokes the copy constructor of Not, because the argument is also of type Not. The copy constructor's signature matches better and it's therefore selected.






share|improve this answer
















  • 3




    More detail: Not(Operator& child) is not a copy-constructor, despite the fact that it can be called with an argument of the same type. The implicitly-defined copy-constructor also exists.
    – M.M
    5 hours ago






  • 3




    As a possible solution, you could take Operator* child, or pass the value with static_const<Operator&>. To avoid the silent copy, you can delete the copy-constructor and use uniform initialization syntax.
    – José Manuel
    4 hours ago














up vote
18
down vote



accepted










Not d = Not(n); invokes the copy constructor of Not, because the argument is also of type Not. The copy constructor's signature matches better and it's therefore selected.






share|improve this answer
















  • 3




    More detail: Not(Operator& child) is not a copy-constructor, despite the fact that it can be called with an argument of the same type. The implicitly-defined copy-constructor also exists.
    – M.M
    5 hours ago






  • 3




    As a possible solution, you could take Operator* child, or pass the value with static_const<Operator&>. To avoid the silent copy, you can delete the copy-constructor and use uniform initialization syntax.
    – José Manuel
    4 hours ago












up vote
18
down vote



accepted







up vote
18
down vote



accepted






Not d = Not(n); invokes the copy constructor of Not, because the argument is also of type Not. The copy constructor's signature matches better and it's therefore selected.






share|improve this answer












Not d = Not(n); invokes the copy constructor of Not, because the argument is also of type Not. The copy constructor's signature matches better and it's therefore selected.







share|improve this answer












share|improve this answer



share|improve this answer










answered 5 hours ago









Angew

129k11240335




129k11240335







  • 3




    More detail: Not(Operator& child) is not a copy-constructor, despite the fact that it can be called with an argument of the same type. The implicitly-defined copy-constructor also exists.
    – M.M
    5 hours ago






  • 3




    As a possible solution, you could take Operator* child, or pass the value with static_const<Operator&>. To avoid the silent copy, you can delete the copy-constructor and use uniform initialization syntax.
    – José Manuel
    4 hours ago












  • 3




    More detail: Not(Operator& child) is not a copy-constructor, despite the fact that it can be called with an argument of the same type. The implicitly-defined copy-constructor also exists.
    – M.M
    5 hours ago






  • 3




    As a possible solution, you could take Operator* child, or pass the value with static_const<Operator&>. To avoid the silent copy, you can delete the copy-constructor and use uniform initialization syntax.
    – José Manuel
    4 hours ago







3




3




More detail: Not(Operator& child) is not a copy-constructor, despite the fact that it can be called with an argument of the same type. The implicitly-defined copy-constructor also exists.
– M.M
5 hours ago




More detail: Not(Operator& child) is not a copy-constructor, despite the fact that it can be called with an argument of the same type. The implicitly-defined copy-constructor also exists.
– M.M
5 hours ago




3




3




As a possible solution, you could take Operator* child, or pass the value with static_const<Operator&>. To avoid the silent copy, you can delete the copy-constructor and use uniform initialization syntax.
– José Manuel
4 hours ago




As a possible solution, you could take Operator* child, or pass the value with static_const<Operator&>. To avoid the silent copy, you can delete the copy-constructor and use uniform initialization syntax.
– José Manuel
4 hours ago










Core is a new contributor. Be nice, and check out our Code of Conduct.









 

draft saved


draft discarded


















Core is a new contributor. Be nice, and check out our Code of Conduct.












Core is a new contributor. Be nice, and check out our Code of Conduct.











Core is a new contributor. Be nice, and check out our Code of Conduct.













 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53046123%2fconstructor-taking-base-is-not-called%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

Long meetings (6-7 hours a day): Being “babysat” by supervisor

What does second last employer means? [closed]

One-line joke