Why doesn't the base class constructor set the values? - c++

Here, values of x and y is being tried to set through base class constructor.
But, the code is unable to do so.
#include <iostream>
class Point2d {
public:
double x;
double y;
Point2d() : x(0), y(0) {
}
Point2d(double x, double y) : x(x), y(y) {
}
void Show() {
std::cout << "(" << x << "," << y << ")\n";
}
};
class Vector2d : public Point2d {
public:
Vector2d():Point2d(){
}
Vector2d(double x, double y) : Point2d(x,y) {
}
Vector2d(Vector2d const& vec) : Point2d(vec){
}
void Set(double x, double y) {
Point2d::Point2d(x, y);
}
};
int main() {
Vector2d v;
v.Set(20, -39);
v.Show(); // prints '(0,0)' instead of '(20,-39)'
}
My target is to reuse base class constructor, and, overloaded assignment operators as much as possible.

I'm afraid your code won't even compile at
void Set(double x, double y)
{
Point2d::Point2d(x, y);
}
A constructor of a base class should be called at the beginning of the member initializer lists of a subclass constructor, not in a member function.
What you need is probably
class Point2d {
public:
double x;
double y;
Point2d() : x(0), y(0) {
}
Point2d(double x, double y) : x(x), y(y) {
}
void Show() {
std::cout << "(" << x << "," << y << ")\n";
}
Point2d& operator=(Point2d const& rhs)
{
this->x = rhs.x;
this->y = rhs.y;
}
};
class Vector2d : public Point2d {
public:
Vector2d():Point2d(){
}
Vector2d(double x, double y) : Point2d(x,y) {
}
Vector2d(Vector2d const& vec) : Point2d(vec){
}
/* also need to be overloaded in the subclass */
Vector2d& operator=(Vector2d const& rhs)
{
Point2d::operator=(rhs);
return *this;
}
void Set(double x, double y) {
*this = Vector2d(x, y);
}
};
int main() {
Vector2d v;
v.Set(20, -39);
v.Show();
}

Well, you're trying to construct the base class in the setter function, but the base class will already be constructed when the derived class is constructed. I would just set the x and y values of the base class in the setter.

Related

error C2248: 'point::x': cannot access private member declared in class 'point'

With this code:
#include <iostream>
using namespace std;
class point{
public:
double get_x();
void set_x(double v);
double get_y();
void set_y(double z);
private:
double x, y;
};
point operator+(point& p1, point& p2)
{
point sum = {p1.x};// + p2.x, p1.y + p2.y};
return sum;
}
int main()
{
point a = {3.5,2.5}, b = {2.5,4.5}, c;
}
I get the following compiler errors saying the private members cannot be accessed:
point.cpp(22): error C2248: 'point::x': cannot access private member declared in class 'point'
point.cpp(17): note: see declaration of 'point::x'
point.cpp(8): note: see declaration of 'point'
I am pretty new to C++ and can't seem to figure out how to resolve this issue. Any help is much appreciated.
You declared x and y as private so they can't be accessed in that function(or outside the class) unless you make that function a friend of the class, but if you want to overload the + operator, you should do it inside the class, something like this :
class point
{
public:
point(double x, double y) // CONSTRUCTOR
:x(x), y(y)
{
}
double get_x() const{
return x;
};
void set_x(double v)
{
x = v;
};
double get_y() const{
return y;
};
void set_y(double z)
{
y = z;
};
point operator+(const point &obj)
{
double newX = this->x + obj.get_x();
double newY = this->y + obj.get_y();
point sum{newX, newY};
return sum;
};
private:
double x, y;
};

How to use overloaded operator== to check if 2d point and 3d point are identical in C++?

I would like to check wether my 2d point and 3d points are identical using operator== that returns true if they are.
How can I implement that?
Do I need to add overloaded operator into both classes or what?
How to compare 2 arguments x and y?
My code:
#include <iostream>
using namespace std;
class Point2D {
public:
Point2D();
// ~Point2D();
void SetX(double x);
void SetY(double y);
double GetX();
double GetY();
protected:
double m_x, m_y;
};
class Point3D :Point2D {
public:
Point3D() :Point2D() { m_z = 0.0; };
protected:
double m_z;
};
Point2D::Point2D() {
m_x = 0.0;
m_y = 0.0;
}
void Point2D::SetX(double x) {
m_x = x;
}
void Point2D::SetY(double y) {
m_y = y;
}
double Point2D::GetX() {
return m_x;
}
double Point2D::GetY() {
return m_y;
}
int main() {
Point2D T;
cout << T.GetX() << " " << T.GetX() << endl;
return 0;
}
First, you probably want public inheritance:
class Point3D : public Point2D {
// ~~~~~~~~~~~~~^
Once you have that, you can rely on polymorphism to handle things for you and only implement comparison operator for Point2D:
// the arguments should be const, but your classes are not const correct
bool operator== (/*const*/ Point2D& lhs, /*const*/ Point2D& rhs)
{
return lhs.GetX() == rhs.GetX() && lhs.GetY() == rhs.GetY();
}
int main() {
Point2D p2;
Point3D p3;
std::cout << std::boolalpha << (p2 == p3);
}
You can further improve it by making your functions const:
class Point2D {
public:
Point2D();
void SetX(double x);
void SetY(double y);
double GetX() const; //here
double GetY() const; //here
protected:
double m_x, m_y;
};
double Point2D::GetX() const { //and here
return m_x;
}
double Point2D::GetY() const { //and here
return m_y;
}
//now you can pass arguments by const reference, no accidental modifications in the operator
bool operator== (const Point2D& lhs, const Point2D& rhs)
{
return lhs.GetX() == rhs.GetX() && lhs.GetY() == rhs.GetY();
}

Why the copy constructor called, when I return just a reference of the object c++

It is the code which I cannot figure out why it is not working the way I want, I look around the internet, but did not some good solution.
Point class:
class Point
{
public:
Point(const Point &) {
cout << "copy constructor was called" << endl;
}
Point(int x, int y) : x(x), y(y) {
}
void setX(int x) {this->x = x;}
void setY(int y) {this->y = y;}
int getX() const { return x; }
int getY() const { return y; }
private:
int x;
int y;
};
Circle class:
class Circle
{
private:
int rad;
Point &location;
public:
Circle(int radius, Point &location) : rad(radius), location(location) {}
int getRad() { return rad; }
Point & getLocation() { return location; }
};
The usage:
int main() {
Point p(23, 23);
Circle c(12, p);
Point p1 = c.getLocation();
p1.setX(200);
cout << p.getX() << endl; // prints 23, which I want to be 200
// copy constructor was called
system("pause");
return 0;
}
In the following line:
Point p1 = c.getLocation();
p1 is not a reference, so basically you're copying the referenced object returned by getLocation(), thus calling copy constructor.
A solution would be to declare p1 as a reference like this:
Point& p1 = c.getLocation();

Using Base pointers to call derived object function

I need to be able to use a base pointer to hold the address of either a
rectangle or a circle. Which one would be determined at run time. I then want to
use the pointers to call different virtual functions depending on which type
they are. I can get this concept to work if the functions only use one Shape
pointer. However many of my functions require two objects to work.
If I use a pure virtual functions, both Rectangle and Circle classes become
abstract and I can not use the objects (error C2259). If I declare the functions
as I did down below, all of the calls go to the Base class Shape. Any help is
greatly appreciated.
class Shape {
public:
virtual double overlappingArea(const Shape&)const {return 0;};
//replacing with a pure virtual function causes the other classes to become abstract
//virtual double overlappingArea(const Shape&)const = 0;
//This returns error C2259 (or pure virtual function has no overload)
//I know this is because the program has no overloads with identical parameters
};
class Rectangle : virtual public Shape {
public:
Rectangle(int X, int Y, int L, int W) : x(X), y(Y), l(L), w(W) {}
double overlappingArea(const Rectangle& R)const {
double area = 1.1;
//code that finds the overlapping area
return area;
}
double overlappingArea(const Circle& C)const {
double area = 1.2;
//code that finds the overlapping area
return area;
}
private:
int x, y, l, w;
};
class Circle: virtual public Shape {
public:
Circle(int X, int Y, int R) : x(X), y(Y), r(R) {}
double overlappingArea(const Rectangle& R)const {
double area = 2.1;
//code that finds the overlapping area
return area;
}
double overlappingArea(const Circle& C)const {
double area = 2.2;
//code that finds the overlapping area
return area;
}
private:
int x, y, r;
};
int main() {
Shape* F1 = new Rectangle(0,0,1,1);
Shape* F2 = new Rectangle(1,1,2,2);
Shape* C1 = new Circle(0,0,1);
Shape* C2 = new Circle(1,1,2);
double areaFF, areaFC, areaCC;
areaFF = F1->overlappingArea(*F2);
areaFC = F1->overlappingArea(*C1);
areaCC = C1->overlappingArea(*C2);
return 0;
}
All the areas end up equaling 0.
I want areaFF = 1.1 , areaFC = 1.2 , areaCC = 2.2
Thanks for the help
Working code if you're interested
#include <iostream>
using namespace std;
class Rectangle;
class Circle;
class Shape {
public:
virtual double overlapwith(const Shape&)const = 0;
virtual double overlap(const Rectangle&)const = 0;
virtual double overlap(const Circle&)const = 0;
};
class Circle : public Shape {
public:
Circle() : x(0), y(0), r(0) {
}
Circle(int X, int Y, int R) : x(X), y(Y), r(R) {
}
double overlapwith(const Shape &with)const {
cout << "\nCirc::overlapwith(const Shap&)const";
return with.overlap(*this);
}
double overlap(const Rectangle &w)const {
cout << "\nCirc::overlap(const Rect&)const";
return 12;
}
double overlap(const Circle &w)const {
cout << "\nCirc::overlap(const Circ&)const";
return 11;
}
private:
int x, y, r;
};
class Rectangle : public Shape {
public:
Rectangle() : x(0), y(0), l(0), w(0) {
}
Rectangle(int X, int Y, int L, int W) : x(X), y(Y), l(L), w(W) {
}
double overlapwith(const Shape &with)const {
cout << "\nRect::overlapwith(const Shap&)const";
return with.overlap(*this);
}
double overlap(const Rectangle &w)const {
cout << "\nRect::overlap(const Rect&)const";
return 22;
}
double overlap(const Circle &w)const {
cout << "\nRect::overlap(const Circ&)const";
return 21;
}
private:
int x, y, l, w;
};
int main() {
Shape* F1 = new Rectangle(0,0,1,1);
Shape* F2 = new Rectangle(1,1,2,2);
Shape* C1 = new Circle(0,0,1);
Shape* C2 = new Circle(1,1,2);
double ff, fc, cf, cc;
ff = F1->overlapwith(*F2);
fc = F1->overlapwith(*C2);
cf = C1->overlapwith(*F2);
cc = C1->overlapwith(*C2);
cout << "\n\n\tff : " << ff
<< "\n\tfc : " << fc
<< "\n\tcf : " << cf
<< "\n\tcc : " << cc;
int pb; cin >> pb;
return 0;
}
Define two more pure virtual methods in the base class, in addition to the existing virtual methods, which can be pure. You will need to do some simple forward declarations:
class Rectangle;
class Circle;
class Shape {
public:
virtual double overlappingArea(const Shape&) const=0;
virtual double overlappingAreaWith(const Rectangle&) const=0;
virtual double overlappingAreaWith(const Circle&) const=0;
};
In each subclass, implement the first virtual method (the existing one) by invoking overlappingAreaWith() for the passed Shape & parameter, passing *this as the parameter:
class Rectangle {
// ...
double overlappingArea(const Shape &with) const override
{
return with.overlappingAreaWith(*this);
}
};
class Circle {
// ...
double overlappingArea(const Shape &with) const override
{
return with.overlappingAreaWith(*this);
}
};
Now, implement the other two overlappingAreaWith() methods in both Circle and Rectangle subclasses. They will now receive the other object, as either a Circle or a Rectangle parameter, as the case may be.
Each subclass is correctly implementing all three pure virtual methods.

Writing classes to be used with unordered_map.

I want to use the boost map and the documentation says I need an equality function and a hash function. I think understand what they should do but since I can't find any examples I'm not sure how to do it so I am looking for a trivial example, like a point class with members x, y or something close.
Edit: Finally got it working. Wish I hadn't had to waste so much time for this. Thanks anyway guys.
#include <boost/functional/hash.hpp>
#include <boost/unordered_map.hpp>
#include <boost/foreach.hpp>
#include <iostream>
namespace test { // class whose source i can't edit
class point
{
public:
float x;
float y;
point() : x(0), y(0) {}
point(int x, int y) : x(x), y(y) {}
point(float x, float y) : x(x), y(y) {}
point(double x, double y) : x((float) x), y((float) y) {}
bool operator==(point const& other) const
{
return x == other.x && y == other.y;
}
};
}
namespace test { // my source file
std::size_t hash_value(point const &p) {
boost::hash<int> hasher;
return hasher(p.x) + hasher(p.y);
}
}
int main() {
boost::unordered_map<test::point, std::string> myMap;
test::point p1(1, 2);
myMap[p1] = "1"; //now it works
std::cout << myMap[p1] << std::endl;
return 0;
}
Equality and hash aren't too tough to define. Equality:
class Point {
int x, y;
bool operator==(const Point& p) {
return (x == p.x && y == p.y);
}
};
Hashing tends to involve specializing a function or class.
template<> class boost::hash<Point> {
public:
size_t operator()(const Point& p) {
return boost::hash<int>(p.x) + boost::hash<int>(p.y);
}
};
You may need to read up on the specifics of your hash_map implementation for details, and you may also want to define a different hash algorithm.
This is right from boost documentation...
class point
{
int x;
int y;
public:
point() : x(0), y(0) {}
point(int x, int y) : x(x), y(y) {}
bool operator==(point const& other) const
{
return x == other.x && y == other.y;
}
};
class point
{
...
friend std::size_t hash_value(point const& p)
{
std::size_t seed = 0;
boost::hash_combine(seed, p.x);
boost::hash_combine(seed, p.y);
return seed;
}
...
};