I've got the below error but it was good learning though.
/usr/include/c++/9/ext/new_allocator.h:145:20: error: call of overloaded ‘Cadbury(int, int)’ is ambiguous 145 | noexcept(noexcept(::new((void *)__p) | ^~~~~~~~~~~~~~~~~~ 146 | _Up(std::forward<_Args>(__args)...))) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from main.cpp:2: Chocolate.h:58:2: note: candidate: ‘Cadbury::Cadbury(float, float, int)’ 58 | Cadbury(float x, float y, int d=0); | ^~~~~ Chocolate.h:57:2: note: candidate: ‘Cadbury::Cadbury(float, float)’ 57 | Cadbury(float x, float y); | ^~~~~ make: *** [makefile:14: main] Error 1
My program is shown below:
#include <iostream> #include "Chocolate.h" using namespace std; int main() { Cadbury c1(-1, -2); Cadbury c2(10, -2); return 0; } /***************************************************************************/ //Chocolate.cpp #include "Chocolate.h" using namespace std; Chocolate::Chocolate() { cout << " Chocolate ()" << endl; setFlavor(0); } Chocolate::Chocolate(int sugar) { cout << " Chocolate (" << sugar << ")" << endl; setFlavor(sugar); } /***************************************************************************/ //Cadbury.cpp #include "Chocolate.h" using namespace std; Cadbury::Cadbury(float x, float y, int sugar) { cout << " Cadbury (" << x << " , " << y << " , " << sugar << ")" << endl; xCFirst = x; yCSecond = y; setFlavor(sugar); } Cadbury::Cadbury(float x, float y) { cout << " Cadbury (" << x << " , " << y << ")" << endl; xCFirst = x; yCSecond = y; } /***************************************************************************/ //Cadbury.h #ifndef CADBURY_H_ #define CADBURY_H_ #include <iostream> #include <memory> class Cadbury; // forward declaration/reference class Chocolate { public: Chocolate(); Chocolate(int sugar); bool setFlavor(int sugar); }; class Cadbury : public Chocolate { public: Cadbury(float x, float y); Cadbury(float x, float y, int sugar=0); private: float xCFirst; float yCSecond; }; #endif /* CADBURY_H_ */
When I called Cadbury c1(-1, -2) two calls of constructor match:
Cadbury(float x, float y);
Cadbury(float x, float y, int sugar=0);
Second constructor matches because third argument has default value 0,
so it is equivalent to call Cadbury c1(-1, -2, 0).
Compiler cannot choose which one to call. So, I made the following changes/separation in my Cadbury.h file.
Method 1 (Removing the default argument initial value)
#include <iostream> #include "Chocolate.h" using namespace std; int main() { Cadbury c1(-1, -2); Cadbury c2(10, -2); return 0; } /***************************************************************************/ //Chocolate.cpp #include "Chocolate.h" using namespace std; Chocolate::Chocolate() { cout << " Chocolate ()" << endl; setFlavor(0); } Chocolate::Chocolate(int sugar) { cout << " Chocolate (" << sugar << ")" << endl; setFlavor(sugar); } /***************************************************************************/ //Cadbury.cpp #include "Chocolate.h" using namespace std; Cadbury::Cadbury(float x, float y) { cout << " Cadbury (" << x << " , " << y << ")" << endl; xCFirst = x; yCSecond = y; } Cadbury::Cadbury(float x, float y, int sugar) { cout << " Cadbury (" << x << " , " << y << " , " << sugar << ")" << endl; xCFirst = x; yCSecond = y; setFlavor(sugar); } /***************************************************************************/ //Cadbury.h #ifndef CADBURY_H_ #define CADBURY_H_ #include <iostream> #include <memory> class Cadbury; // forward declaration/reference class Chocolate { public: Chocolate(); Chocolate(int sugar); bool setFlavor(int sugar); }; class Cadbury : public Chocolate { public: Cadbury(float x, float y); Cadbury(float x, float y, int sugar); private: float xCFirst; float yCSecond; }; #endif /* CADBURY_H_ */
Cadbury class has these 2 constructors.
Cadbury(float x, float y);
Cadbury(float x, float y, int sugar);
I also added the default constructor in addition to the above.
Cadbury();
Output
Chocolate () setFlavor(0) Cadbury (0 , 0 , 0) setFlavor(0)
With this method, Cadbury constructor with 3 arguments is executed even the c1 object has only 2 arguments. I find that it is not necessary to have the constructor cadbury with 2 arguments itself.
But, if remove the constructor Cadbury(float x, float y);, it will lead to this error because it doesn't know what would be the value for the third argument. We also don't have the default value for the third argument.
error: no matching function for call to ‘Cadbury::Cadbury(float, float)
Method 2
So, I decided to simplify and sort this problem with default value (0) with maximum arguments (3 arguments) passed.
#include <iostream> #include "Chocolate.h" using namespace std; int main() { Cadbury c1(-1, -2); Cadbury c2(10, -2); return 0; } /***************************************************************************/ //Chocolate.cpp #include "Chocolate.h" using namespace std; Chocolate::Chocolate() { cout << " Chocolate ()" << endl; setFlavor(0); } Chocolate::Chocolate(int sugar) { cout << " Chocolate (" << sugar << ")" << endl; setFlavor(sugar); } /***************************************************************************/ //Cadbury.cpp #include "Chocolate.h" using namespace std; Cadbury::Cadbury(float x, float y, int sugar) { cout << " Cadbury (" << x << " , " << y << " , " << sugar << ")" << endl; xCFirst = x; yCSecond = y; setFlavor(sugar); } /***************************************************************************/ //Cadbury.h #ifndef CADBURY_H_ #define CADBURY_H_ #include <iostream> #include <memory> class Cadbury; // forward declaration/reference class Chocolate { public: Chocolate(); Chocolate(int sugar); bool setFlavor(int sugar); }; class Cadbury : public Chocolate { public: Cadbury(float x, float y, int sugar=0); private: float xCFirst; float yCSecond; }; #endif /* CADBURY_H_ */
Output
Chocolate () setFlavor(0) Cadbury (0 , 0 , 0) setFlavor(0)
Method 3
#include <iostream> #include "Chocolate.h" using namespace std; int main() { Cadbury c1(-1, -2); Cadbury c2(10, -2); return 0; } /***************************************************************************/ //Chocolate.cpp #include "Chocolate.h" using namespace std; Chocolate::Chocolate(int sugar) { cout << " Chocolate (" << sugar << ")" << endl; setFlavor(sugar); } /***************************************************************************/ //Cadbury.cpp #include "Chocolate.h" using namespace std; Cadbury::Cadbury(float x, float y, int sugar) : Chocolate(sugar) { cout << " Cadbury (" << x << " , " << y << " , " << sugar << ")" << endl; xCFirst = x; yCSecond = y; } /***************************************************************************/ //Cadbury.h #ifndef CADBURY_H_ #define CADBURY_H_ #include <iostream> #include <memory> class Cadbury; // forward declaration/reference class Chocolate { public: Chocolate(int sugar); bool setFlavor(int sugar); }; class Cadbury : public Chocolate { public: Cadbury(float x, float y, int sugar = 0); private: float xCFirst; float yCSecond; }; #endif /* CADBURY_H_ */
Output
Chocolate (0) setFlavor(0) Cadbury (0 , 0 , 0)
It worked like charm. I think you had very good time learning this!!
Comments
Post a Comment