I am attempting to add a copy constructor to each in order to run the main function. What I have implemented right now currenrtly prints out "b2.valuea = -858993460 b2.valueb = 10" So it reads valueb correctly but obviously something is going wrong with valuea. Advice?
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
int valuea;
public:
int getValuea() const { return valuea; }
void setValuea(int x) { valuea = x; }
// copy constructor
A() {}
A(const A& original)
{
valuea = original.valuea;
}
};
class B : public A
{
int valueb;
public:
int getValueb() const { return valueb; }
void setValueb(int x) { valueb = x; }
// copy constructor
B(){}
B(const B& original)
{
valueb = original.valueb;
}
};
int main()
{
B b1;
b1.setValuea(5);
b1.setValueb(10);
B b2(b1);
cout << "b2.valuea = " << b2.getValuea() << "b2.valueb = " <<
b2.getValueb() << endl;
}
You are not calling the copy constructor of your base-class in your derived copy constructor.
Change it like:
B(const B& original) : A(original){
valueb = original.valueb;
}
And it will output
b2.valuea = 5
b2.valueb = 10
Related
I want to make an operator= and copy constructor, to be called in the inherited class.
For normal objects, it works fine, but when I'm trying to call, for example, operator= with a pointer, it is just copying the object address.
So my question is, how can I call those methods with pointers?
#include <iostream>
// base class
class a {
public:
//constructors
a(): x(0), y(1), z(0){ std::cout << "no parameter constructor A\n"; }
a(int a, int b, int c) :x(a), y(b), z(c){ std::cout << "parameter constructor A\n"; }
a(const a& ob):x(ob.x), y(ob.y), z(ob.z)
{
std::cout << "copy constructor A\n";
}
//operator
a& operator=(const a& obj)
{
if (this != &obj)
{
x = obj.x;
y = obj.y;
z = obj.z;
}
std::cout << "operator = A\n";
return *this;
}
protected:
int x, y, z;
};
//child class
class b : public a
{
public:
//constructors
b() : p(0){ std::cout << "no parameter constructor B\n"; }
b(int X, int Y, int Z, int B) : a(X, Y, Z), p(B) { std::cout << "parameter constructor B\n"; }
b(const b& obj) :p(obj.p), a(obj)
{
std::cout << "copy constructor B\n";
}
//operator =
b& operator=(const b &obj)
{
if (this != &obj)
{
p = obj.p;
&a::operator=(obj);
}
std::cout << "operator = B\n";
return *this;
}
private:
int p;
};
int main()
{
b obj0(4, 8, 16, 32);
b obj1(obj0); // copy constructor
b obj2;
obj2 = obj1; // operator =
std::cout << std::endl << std::endl;
std::cout << "for pointers:\n\n";
a* obj3 = new b(4, 8, 16, 32);
a* obj4(obj3);
obj4 = obj3;
return 0;
}
One of the purposes of using pointers (or references) is to avoid needing to create a copy of the object. Passing a pointer to the object allows the receiver to refer to and manipulate on the original object.
If you wish the pointer to receive a new object, then you would use new.
When dealing with polymorphism as in your example, you would probably need a virtual method that creates a proper clone (sometimes called a deep copy).
class a {
//...
virtual a * clone () const = 0;
};
class b : public a {
//...
b * clone () const {
return new b(*this);
}
};
//...
a *obj4 = obj3->clone();
//...
We leverage that b * is a covariant return type for a *, so that b::clone() can return a b *, but a::clone() can use the b::clone() as an override and still return an a *.
given following piece of code:
#include <iostream>
class A
{
public:
int a;
A() : a(0) {}
};
class B : public A
{
public:
int b;
B(int b) : b(b) {}
B() {}
};
int main()
{
B new_b;
new_b.b = 5;
new_b.a = 4;
std::cout << new_b.a << std::endl;
new_b = B(2); // at this point I want to keep new_b.a
std::cout << new_b.a << std::endl;
}
What is the correct way of achiving this? I know I could overload B's assignment operator and only take over new_b.b here, but is this the proper way of keeping B.a's value?
Thanks for any help on this issue.
Kind Regards,
Steve
#include <iostream>
class A
{
public:
int a;
A() : a(0) {}
};
class B : public A
{
public:
int b;
B(int b) : b(b) {}
B() : b(0) {}
B operator = (B ob) // using operator overloading, the = operator is overloaded
{
b = ob.b;
return b;
}
};
int main()
{
B new_b;
new_b.b = 5;
new_b.a = 4;
std::cout << new_b.a << std::endl;
new_b = B(2); /* Previously a new object of class B with parameterized constructor was made and copied to new_b which created a new object of class A everytime.
Now as the = operator is overloaded, it just copies the value(2) into new_b without creating a new object of class B or A thus the original value of A::a is preserved*/
std::cout << new_b.a << std::endl;
std::cin.get();
}
Hi this is my first time posting an answer, hope I was clear enough for you to understand, if you have a problem I'd be happy to help again
Let's say we have the following scenario:
We have a base abstract class A. Then we have classes B and C which derived from A. We also have class D which is a custom implementation of a std::vector<T> - it contains a private property list of type std::vector<T> and some custom methods to work with it.
Now my problem is as follows: I would like to overload the operator + in class A to be able to do this:
B* b = new B();
C* c = new C();
D mList = b+c; //the property *list* of mList would contain b an c
I have tried everything and can't seem to be able to get it to work and am out of ideas. Is it even possible to override an operator in a base abstract class so that it will apply to derived classes?
EDIT:
Here is what I have tried so far:
File A.h:
#pragma once
#include <string>
#include <iostream>
using namespace std;
class A
{
protected:
double price;
string name;
public:
A() :name(""){};
A(string n, double p){
price = p;
name = n;
};
~A(){};
virtual void calculate(double value) = 0;
virtual void print() const = 0;
};
File B.h:
#pragma once
#include "A.h"
class B : public A
{
private:
public:
B() :A(){};
B(string n, double p) :A(n,p){};
~B();
void calculate(double value)
{
price = price + value;
}
void print() const
{
cout << name << " says: " << " " << price;
}
};
File C.h:
#include "A.h"
class C : public A
{
private:
public:
C() :A(){};
C(string n, double p) : A(n,p){};
~C();
void calculate(double value)
{
price = price * value;
}
void print() const
{
cout << name << " says: " << " " << price;
}
};
File D.H:
#include <vector>
class D
{
private:
vector<A*> list;
public:
D(){}
~D()
{
int len = list.size();
for (int i = 0; i < len; i++)
{
delete list[i];
}
};
void push(A* item)
{
list.push_back(item);
}
A* pop()
{
A* last = list.back();
list.pop_back();
return last;
}
//I have tried overriding it here and in A.h
friend D D::operator+(A* first, A* second)
{
D temp;
temp.push(first);
temp.push(second);
return temp;
}
};
It looks like you're are adding two pointers, so A::operator+() won't even be called. But to answer your question, yes, operator overloading is inheritable. Even from an abstract base class.
class A
{
public:
virtual void test() = 0;
int operator+(const A &a) {return 42;}
};
class B : public A
{
void test() {};
};
class C : public A
{
void test() {};
};
int main()
{
B* b = new B();
C* c = new C();
cout << "result: " << *b + *c << endl;
return 0;
}
Output:
result: 42
When c in C* and d is a D* if you write c+d you're just adding pointers, whatever overloads you defined.
Maybe you could redefine pointer addition for A* with a global operator(A*, A*) (not sure it's possible) but it would be quite dangerous for users since it overrides standard behavior.
The better solution is to define operators on references (const) and not pointers, which in your case is a little less convenient since you'd have to write: list = *c + *d;
Also, since you're using containers of pointers for polymorphism, I strongly recommend using shared_ptr.
Working code below (simplified, but with the ability to add more than 2 elements):
#include <list>
using std::list;
struct A {
list<const A*> operator+(const A& right) { // A + A
list<const A*> r;
r.push_back(this);
r.push_back(&right);
return r;
}
list<const A*> operator+(const list<const A*> & right) { // A + list
list<const A*> r = right;
r.push_front(this);
return r;
}
virtual void print() const = 0;
};
list<const A*> operator+(const list<const A*> & left, const A & right) { // list + A
list<const A*> r = left;
r.push_back(&right);
return r;
}
#include <iostream>
struct B : A {
void print() const { std::cout << "B" << std::endl; }
};
struct C : A {
void print() const { std::cout << "C" << std::endl; }
};
int main() {
B b;
C c;
B* pb = new B;
list<const A*> lst = b + c + *pb;
for(list<const A*>::iterator i = lst.begin(); i != lst.end(); ++i) {
(*i)->print();
}
return 0;
}
Take a look at this code-example:
#include <iostream>
class B;
class A;
class A
{
public:
virtual void overrideProp() = 0;
friend int operator+(const B& b, const A& a);
friend std::ostream& operator<<(std::ostream& os, const A& a)
{
return os << a.prop;
}
protected:
int prop;
};
class B : public A
{
public:
B(){overrideProp();}
void overrideProp(){prop=1;}
};
class C : public A
{
public:
C(){overrideProp();}
void overrideProp(){prop=3;}
};
int operator+(const B& b, const A& a)
{
return b.prop + a.prop;
}
class D
{
public:
void operator=(const int& i){d = i;}
friend std::ostream& operator<<(std::ostream& os, const D& a)
{
return os << a.d;
}
private:
int d;
};
int main()
{
B b;
C c;
D d; d = b+c;
std::cout << "B contains: " << b << " C contains: " << c << " D contains: " << d;
}
The output is B contains: 1 C contains: 3 D contains: 4
Here's an compilable and runnable example (http://codepad.org/cQU2VHMp) I wrote before you clarified the question, maybe it helps. The idea is that the addition overload can either be unary (and D defined as a friend), as here, or defined as a non-member binary operator using public methods. Note that I have to dereference the pointers b and c to make this work, as adding pointers often don't make sense.
#include <iostream>
#include <string>
class D {
public:
void Foo() {
std::cout << "D: " << member_ << std::endl;
}
friend class A;
private:
std::string member_;
};
class A {
public:
virtual void Foo() = 0;
A(const std::string &member) : member_(member) {}
D operator+(const A &rhs) {
D out;
out.member_ = member_ + " " + rhs.member_;
return out; // Uses the default copy constructor of D
}
protected:
std::string member_;
};
class B : public A {
public:
B(const std::string &member) : A(member) {}
void Foo() {
std::cout << "B: " << member_ << std::endl;
}
};
class C : public A {
public:
C(const std::string &member) : A(member) {}
void Foo() {
std::cout << "C: " << member_ << std::endl;
}
};
int main() {
B *b = new B("hello");
C *c = new C("world");
b->Foo();
c->Foo();
D d = (*b) + (*c);
d.Foo();
delete b;
delete c;
return 0;
}
The output of this program is:
B: hello
C: world
D: hello world
Can someone please explain why i->value() and (i + 1)->value() prints 1 and 3 not 1 and 4 like x[0]->value() << x[1]->value()
#include <iostream>
#include <vector>
class A
{
public:
A(int n = 0) : m_n(n) { }
public:
virtual int value() const { return m_n; }
virtual ~A() { }
protected:
int m_n;
};
class B
: public A
{
public:
B(int n = 0) : A(n) { }
public:
virtual int value() const { return m_n + 1; }
};
int main()
{
const A a(1); //a.m_n=1
const B b(3); //b.m_n=3
const A *x[2] = { &a, &b };
typedef std::vector<A> V;
V y;
y.push_back(a);
y.push_back(b);
V::const_iterator i = y.begin();
std::cout << x[0]->value() << x[1]->value()
<< i->value() << (i + 1)->value() << std::endl;
return 0;
}
Thank you
y.push_back(b); creates an instance of A which is a copy of the A subobject in b, and pushes that onto the vector. There are no instances of B on the vector, nor could there be, so B::value() is not called. Read about object slicing
void push_back (const value_type& val);
will create an A copy of val if the vector is defined as std::vector<A> V.
You see here so called slicing problem.
This is why you should use
std::vector<A*> V
or
std::vector<shared_ptr<A> > V
In the code show below, how do I assign rvalue to an object A in function main?
#include <iostream>
using namespace std;
class A
{
public:
int* x;
A(int arg) : x(new int(arg)) { cout << "ctor" << endl;}
A(const A& RVal) {
x = new int(*RVal.x);
cout << "copy ctor" << endl;
}
A(A&& RVal) {
this->x = new int(*RVal.x);
cout << "move ctor" << endl;
}
~A()
{
delete x;
}
};
int main()
{
A a(8);
A b = a;
A&& c = A(4); // it does not call move ctor? why?
cin.ignore();
return 0;
}
Thanks.
Any named instance is l-value.
Examples of code with move constructor:
void foo(A&& value)
{
A b(std::move(value)); //move ctr
}
int main()
{
A c(5); // ctor
A cc(std::move(c)); // move ctor
foo(A(4));
}