C ++运算符在抽象类中重载

时间:2014-05-25 09:15:32

标签: c++ inheritance overloading operator-keyword abstract

假设我们有以下情况:

我们有一个基础抽象类A。然后我们有来自B的课程CA。我们还有一个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;
    }
};

4 个答案:

答案 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