假设我们有以下情况:
我们有一个基础抽象类A
。然后我们有来自B
的课程C
和A
。我们还有一个D
类,它是std::vector<T>
的自定义实现 - 它包含list
类型的私有属性std::vector<T>
以及一些自定义方法来处理它。
现在我的问题如下:我想重载课程operator +
中的A
,以便能够执行此操作:
B* b = new B();
C* c = new C();
D mList = b+c; //the property *list* of mList would contain b an c
我已经尝试了所有的东西,但似乎无法让它发挥作用并且没有想法。是否可以覆盖基本抽象类中的运算符,以便它将应用于派生类?
编辑:
这是我到目前为止所尝试的内容:
档案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;
};
文件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;
}
};
档案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;
}
};
文件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;
}
};
答案 0 :(得分:0)
这是一个可编辑且可运行的示例(http://codepad.org/cQU2VHMp),在您澄清问题之前我写过,也许这有帮助。这个想法是加法重载可以是一元(和D定义为朋友),如此处,或使用公共方法定义为非成员二元运算符。请注意,我必须取消引用指针b和c才能使其工作,因为添加指针通常没有意义。
#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;
}
该程序的输出是:
B: hello
C: world
D: hello world
答案 1 :(得分:0)
c in C*
和d is a D*
如果你写c+d
,你只是添加指针,无论你定义了什么重载。
也许您可以使用全局A*
重新定义operator(A*, A*)
的指针添加(不确定它是否可行),但这对用户来说非常危险,因为它会覆盖标准行为。
更好的解决方案是在引用上定义运算符(const)而不是指针,在你的情况下,由于你不得不写:[{1}}
此外,由于您使用指针容器进行多态,我强烈建议您使用list = *c + *d;
。
下面的工作代码(简化,但能够添加2个以上的元素):
shared_ptr
答案 2 :(得分:0)
看起来你正在添加两个指针,所以甚至不会调用A :: operator +()。但回答你的问题,是的,运营商重载是可继承的。即使是从一个抽象的基类。
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;
}
输出:
result: 42
答案 3 :(得分:0)
看看这段代码示例:
#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;
}
输出为B contains: 1 C contains: 3 D contains: 4