(C++) Constructor, default parameters, "call of overloaded... ambigous" - c++

i'm new to this site, after doing some research I could not find a problem similar to mine(some questions looked like mine but their code was different)
So basically what i'm trying to do is to representing the framebuffer matrix with all different colors values. I'm coding a class named "Point", and I have one constructor, using default arguments, here it is :
Point.h
#ifndef POINT_H
#define POINT_H
#include <iostream>
class Point
{
protected:
int x;
int y;
public:
Point(int=0,int=0);
Point(const &Point);
void showC() const;
static void showC(Point);
virtual ~Point();
};
#endif // POINT_H
Point.cpp
#include "Point.h"
using namespace std;
Point::Point(int a,int b)
{
x=a;
y=b;
}
Point::~Point()
{}
void Point::showC() const
{ cout << x << " " << y << endl; }
void Point::showC(Point P)
{ cout << P.x << " " << P.y << endl; }
But the problem is when I try to compile the program
main.cpp
#include <iostream>
#include "Point.h"
using namespace std;
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
cout << "Call of function member showC\n";
P1.showC();
P2.showC();
P3.showC();
cout << "Call of static function showC\n";
Point::showC(P1);
Point::showC(P2);
Point::showC(P3);
return 0;
}
There is an error when I create Point P2 :
"Call of overloaded 'Point(int)' is ambigous"
On all the others question i read, either it was not the same problem or they had a default constructor in addition to a constructor with default argument which cause ambiguity of which constructor to use if you create an object without argument.
On a book i'm reading to improve skills on c++, there is this sample that is working somehow, and that's why I don't really understand
Here is the sample :
main.cpp
class point
{
private :
int x;
int y;
Point (int abs=0, int ord=0) //inline constructor
{x=abs; y=ord;}
bool coincide(point);
};
bool point::coincide(point pt)
{ return ( (pt.x==x) && (pt.y==y) );
}
int main()
{
point a, b(1), c(1,0);
cout << "a and b : " << a.coincide(b) << " ou " b.coincide(a) << "\n"
cout << "b et c : " << b.coincide(c) << " ou " << c.coincide(b) << "\n"
}
However he grouped everything in the main.cpp files, and his constructor is inline.
Can anyone explain to me why is the sample working, and why my program is not ? I guess there is a mechanism that i don't understand...
Thanks in advance
RE-EDIT : I copied all the code

I think you are mixing both python and c++ way of creating class
python do use : class Point:
for declaring in class , c++ uses {} like class Point {};
Below works by changing the class declaration.
Just added a cout in your constructor
#include <iostream>
#include <vector>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int=0,int=0);
};
Point::Point(int a, int b)
{
x = a;
y = b;
cout<<x<<y<<endl;
}
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
return 0;
}
Output
00
20
4-7
Program ended with exit code: 0
After question edit
Removed your buggy line and it works perfectly
Point(const &Point);
#include <iostream>
#include <vector>
using namespace std;
class Point
{
protected:
int x;
int y;
public:
Point(int=0,int=0);
//Point(const &Point);
void showC() const;
static void showC(Point);
virtual ~Point();
};
Point::Point(int a,int b)
{
x=a;
y=b;
}
Point::~Point()
{}
void Point::showC() const
{ cout << x << " " << y << endl; }
void Point::showC(Point P)
{ cout << P.x << " " << P.y << endl; }
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
cout << "Call of function member showC\n";
P1.showC();
P2.showC();
P3.showC();
cout << "Call of static function showC\n";
Point::showC(P1);
Point::showC(P2);
Point::showC(P3);
return 0;
}
Output
Call of function member showC
0 0
2 0
4 -7
Call of static function showC
0 0
2 0
4 -7
Program ended with exit code: 0
After edit I guess you want to use copy constructor just change it to
Point(const Point &p2) {x = p2.x; y = p2.y; }

Related

My setter doesn't work in new class (inheritance)

This is my code. I created base class and in constructor set x=0. Next I used virtual set_x() = 0. And I created set_x() in new class. Output:
set x
100
DONE. Let's check. 0500
Why I got 0500 not 100500?
#include "mainwindow.h"
#include <QApplication>
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
struct invalid_file_handler : std::runtime_error{
using runtime_error::runtime_error;
};
class base_class{
private:
int x;
int y;
public:
virtual void set_x()=0;
void set_y(){
this->y=500;
}
int get_x(){
return (this->x);
}
int get_y(){
return (this->y);
}
base_class(){
this->x=0;
this->y=0;
}
};
class new_class :public base_class{
public:
void set_x();
private:
int z;
int x;
int y;
};
void new_class::set_x(){
cout << "set x " << endl;
this->x=100;
cout << this->x << endl << "DONE. Let's check. ";
}
int main()
{
ifstream my_open_file;
string file_path = "/home/wojtek/Pulpit/elo.odt";
try{
my_open_file.open("/home/wojtek/Pulpit/elo.odt");
my_open_file.close();
}catch (std::runtime_error &e){
cerr << "Hello Xd XD chua" << endl;
cerr << e.what();
}
ofstream myfile;
try{
myfile.open ("/home/wojtek/Pulpit/example.txt");
myfile << "Writing this to a file.\n";
myfile.close();
}
catch(invalid_file_handler &e){
cerr << "Hello!" << endl;
}
new_class *object = new new_class();
object->set_x();
cout << object->get_x();
object->set_y();
cout << object->get_y();
//base_class object;
//cout << object.get_y();
return 0;
}
The variables x and y declared in new_class are shadowing the variables with the same names declared in base_class. This means that in any member method of new_class, the name x refers to new_class::x and not base_class::x.
Simply remove these lines from the new_class definition:
int x;
int y;
And make the same members in the base_class protected instead of private so that the new_class also has access:
class base_class{
protected:
int x;
int y;
Note: your code has a memory leak, since you never delete object after allocating it. Always delete what you new, and don't use new unless you really need to.

Coupling when achieve a component pattern in a c++ render

Now,I hava a class with some components to do things while these components also need the reference of this parent class to update states.They coupling with each other make the design hard.Here is a example code snippet:
#include<iostream>
#include <windows.h>
#include <math.h>
using namespace std;
class man {
public:
int health{ 10 }, x, y;
void update();
private:
class moveCom *_move;
class judgeCom *_judge;
};
class moveCom {
public:
void update(man&m) {
++m.x;
++m.y;
}
};
class judgeCom {
public:
void update(man&m) {
if(rand()%10 <= 5)
++m.health;
else --m.health;
}
};
void man::update() {
_move->update(*this);
_judge->update(*this);
cout << health << " " << x << " " << y << endl;
}
int main() {
man m;
while (1) {
Sleep(200);
m.update();
}
return 0;
}
This code can only work in the same cpp file which means if split them into different hpp/cpp will cause compile error.Is there any practice to do better?
Edit:Sorry,i try it again and it okay with separate.

Pointer Function return value of Struct in Class [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
I have been attempting to create a function getLocation() that utilizes a pointer to return the value of the struct Location declared in the Character class. I was curious as to the problem with my syntax (or my structure). Knowing that the asterisk * should refer to the value, why is it that my function using an ampersand string& Character::getInventory is able to return the value of that particular index (its return does not need to be converted)?
Trying Location& Character::getLocation() {return position; }
when run results in error C2679: binary '<<': no operator found
Nor
Location*
Which cannot be run as there is no conversion.
I read that the following is likely the most proper because it specifies the scope in which the structure resides, but still results in needing and returning a temporary.
Character::Location* const & Character::getLocation() {return &position; }
Any advice or input would be greatly appreciated, thanks in advance.
Below is my main.cpp, which of course will show the hexadecimal address for Location.
#include <iostream>
#include <string>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::string;
class Character {
private:
string name;
string inventory[4];
public:
struct Location {
int x; int y;
};
Location position;
public:
void Character::setName(string x) { name = x; }
string Character::getName() { return name; }
void Character::setLocation(int x, int y) {
position.x = x; position.y = y;
}
Location* Character::getLocation() {return &position; }
void Character::setInventory(string(&x)[4]) { for (int i = 0; i < 4; ++i) { inventory[i] = x[i]; } }
string& Character::getInventory(int itemNumber) { return inventory[itemNumber]; }
};
void showUser(Character Character);
int main() {
try {
string items[4] = { "Sword", "Shield", "Potion", "Cloak" };
Character CharacterI;
CharacterI.setName("Some Character");
CharacterI.setInventory(items);
CharacterI.setLocation(1, 30);
cout << "\n" << "Retrieving Character Info..." << "\n" << endl;
showUser(CharacterI);
}
catch (std::exception & e) {
cerr << "\nError : " << e.what() << '\n';
}
system("pause");
return 0;
}
void showUser(Character character) {
cout << "Name : " << character.getName() << endl;
cout << "Location : " << character.getLocation() << endl;
for (int i = 0; i < 4; ++i) {
cout << "Inventory " << i + 1 << " : " << character.getInventory(i) << endl;
}
}
Ok, I think I understand the question better now. The reason why getInventory can successfully return a reference while getLocation does not is because getLocation returns a reference to a temporary variable, which is not good. See the link in #NathanOliver's comment for details. Additionally, to paraphrase a previous comment by #Peter Schneider, an * in an expression dereferences a pointer to return a value, while in a declaration it signifies that a variable will be of pointer type. The two usages are more or less opposites of each other. Example:
int* p = new int; //Declares a pointer to int
int x = *p; //Dereferences a pointer and returns an int
What you need to do is create a member variable to hold the Character's location, then set/get from that variable instead of creating temporaries. You did this already for name and inventory, just keep using that same pattern.
Additionally, whenever you use the Location struct outside of the Character class scope, you need to fully-qualify it with Character::Location.
Example:
#include <iostream>
using namespace std;
class Character {
public:
struct Location {
int x;
int y;
};
Location loc;
void SetLocation(int x, int y) {loc.x = x; loc.y = y;}
Location& GetLocation() {return loc;}
};
int main ()
{
Character c;
c.SetLocation(1,42);
Character::Location l = c.GetLocation();
cout << l.x << endl << l.y << endl;
return 0;
}
Output:
1
42

Derived Classes Error

I finished a small program using derived classes and it compiles correctly, but the output is wrong.
The program uses an ordered pair (x, y) as the center for a circle. It then uses the center and the radius given to determine the area and circumference of the circle.
Outputting ordered pairs with the pointType class works fine, but when I tested the circleType class I expected to get (0, 0) as a default. Instead I got (2293512, 2293700)
Any help given will be appreciated!
Here's the point class code:
#ifndef POINTTYPE_H_INCLUDED
#define POINTTYPE_H_INCLUDED
#include <iostream>
class pointType{
public:
pointType (int=0, int=0);
int getX() const;
int getY() const;
void setX(int);
void setY(int);
void setValues(int, int);
friend pointType operator + (pointType, pointType);
friend pointType operator - (pointType, pointType);
friend std::ostream& operator << (std::ostream&, pointType);
private:
int x;
int y;
};
#endif // POINTTYPE_H_INCLUDED
Here's the point class implementation:
#include "pointType.h"
pointType::pointType (int X, int Y) : x(X), y(Y) {}
int pointType::getX () const {
return x;
}
int pointType::getY () const {
return y;
}
void pointType::setX (int new_x) {
x = new_x;
}
void pointType::setY (int new_y) {
y = new_y;
}
void pointType::setValues (int new_x, int new_y) {
x = new_x;
y = new_y;
}
pointType operator + (pointType lh, pointType rh){
pointType answer;
answer.x = lh.x + rh.x;
answer.y = lh.y + rh.y;
return answer;
}
pointType operator - (pointType lh, pointType rh){
pointType answer;
answer.x = lh.x - rh.x;
answer.y = lh.y - rh.y;
return answer;
}
std::ostream& operator << (std::ostream& out, pointType c){
out << "(" << c.x << ", " << c.y << ")";
return out;
}
Here's the circle class:
#ifndef CIRCLETYPE_H_INCLUDED
#define CIRCLETYPE_H_INCLUDED
#include "pointType.h"
#include <iostream>
class circleType: protected pointType {
public:
circleType (float=0);
circleType (int=0, int=0);
void setRadius (float);
float calculateArea (float);
float calculateCircumference (float);
friend std::ostream& operator << (std::ostream&, circleType);
private:
float radius;
int center_x;
int center_y;
};
#endif // CIRCLETYPE_H_INCLUDED
Here's the circle class implementation:
#include "pointType.h"
#include "circleType.h"
#include <math.h>
const float PI = 3.14;
circleType::circleType(float R): radius(R) {}
circleType::circleType(int center_X, int center_Y):
pointType(center_x, center_y) {}
void circleType::setRadius(float new_radius) {
radius = new_radius;
}
float circleType::calculateArea(float radius) {
float area;
area = PI * pow(radius, 2);
return area;
}
float circleType::calculateCircumference(float radius) {
float circumference;
circumference = PI * (radius * 2);
return circumference;
}
std::ostream& operator << (std::ostream& odata, circleType f) {
odata << "(" << f.center_x << ", " << f.center_y << ")";
return odata;
}
Here's the testing code:
#include "pointType.h"
#include "circleType.h"
#include <iostream>
#include <math.h>
using namespace std;
int main() {
pointType c, d(8, 9);
circleType f(4, 5);
cout << c << endl;
cout << d << endl;
c.setValues(12, 3);
cout << c << endl;
cout << c + d << endl;
cout << c - d << endl;
cout << f << endl;
return 0;
}
As far as I can see, the circleType int members center_x and center_y are never set. Your constructor CircleType::CircleType(int=0,int=0) calls the base constructor, which in turn set pointType.x and pointType.y, both private members of the base class (and hence not available to circleType).
My suggestion (or what I think you intended\expected): make int x and int y protected, not private, and remove center_x and center_y, then print odata << "(" << f.x << ", " << f.y << ")";
Its a typo.
circleType::circleType(int center_X, int center_Y):
pointType(center_x, center_y) {}
Notice the difference between center_X (uppercase) and center_x (lowercase).
You pass your uninitialized members to the parent constructor which can have any value lingering at the stack.
Therefor it is good practive to always preceed your members with m_ e.g: m_centerX. (In this particular case it isnt even neccessary to have them again in the child class, redundancy is bad!)
EDIT:
Sorry for the confusion, but please be more precisly next time, could have saved us all alot of time. I assumed that your problems occurs when adding a point with a circle, after running the code by my own I noticed that it happens when outputting f. The reason is the same as explained above: you dont initialize your members! They simply hold any value which were currently at the memory location the object becomes constructed.
In your circleType class, center_x and center_y aren't being initialised. The parameters are being passed directly to the pointType constructor and setting the private members. You can prove this by changing the operator<< function that takes a circleType argument:
std::ostream& operator << (std::ostream& odata, circleType f) {
odata << "(" << f.center_x << ", " << f.center_y << ")" << std::endl;
odata << "(" << f.getX() << ", " << f.getY() << ")"; //access superclass
return odata;
}
With protected inheritance, you also can't use the + and - overloads defined for the base class either, it won't compile.

std::map<string, class> print the value of the key

My program is written in C++.
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Details
{
int x;
int y;
};
typedef std::map<string, Details> Det;
Det det;
Details::Details(int p, int c) {
x = p;
y = c;
}
int main(){
det.clear();
insertNew("test", 1, 2);
cout << det["test"] << endl;
return 0;
}
I want to print the value of a key with the simplest way. Eg det["test"] fails to compile.
How to I print values (1,2) for (x,y) that correspond to key "test"?
My best guess is that you have no default or copy constructor in your Obj (you don't have any in the code you posted, but I assume you have one that takes two integers). You've also got a typo in the catalog.insert() line. Here is what worked for me, using your code:
class Obj {
public:
Obj() {}
Obj(int x, int y) : x(x), y(y) {}
int x;
int y;
};
int main (int argc, char ** argv) {
std::map<std::string, Obj> catalog;
catalog.insert(std::map<std::string, Obj>::value_type("test", Obj(1,2)));
std::cout << catalog["test"].x << " " << catalog["test"].y << std::endl;
return 0;
}
Create an operator<< for your class Obj and then you can do something like std::cout << catalog["test"]; (I'm assuming that the missing parens in the insert call are just a copy-paste-o).
I've changed a bit your code.
#include <map>
#include <iostream>
#include <string>
using namespace std;
class Obj {
public:
Obj( int in_x, int in_y ) : x( in_x ), y( in_y )
{};
int x;
int y;
};
int main()
{
std::map< string, Obj* > catalog;
catalog[ "test" ] = new Obj(1,2);
for( std::map<string, Obj*>::iterator i=catalog.begin(); i != catalog.end(); ++i )
{
cout << "x:" << i->second->x << " y:" << i->second->y << endl;
}
}
Given these types:
class Obj {
int x;
int y; };
std::map<string, Obj> catalog;
Given a populated catalog object:
for(auto ob = catalog.begin(); ob != catalog.end(); ++ob)
{
cout << ob->first << " " << ob->second.x << " " << ob->second.y;
}