Вызов функции родительского класса для сравнения родительского и дочернего классов - PullRequest
0 голосов
/ 13 июня 2018

Я проходил курс Python, и появилась идея использовать переопределенную функцию родителей для сравнения родительских и дочерних классов.В основном:

class A(object):
    def __init__(self,a):
        self.a = a

    def __lt__(self,other):
        return self.a < other.a

class B(A):
    def __init__(self,a,b):
        self.a = a
        self.b = b

    def __lt__(self,other):
        return self.b < other.b

a = A(2)
b = B(1,3)
print(a < b)
#print(b < a) # AttributeError: 'A' object has no attribuite 'b'
print(A.__lt__(b,a)) # so we call this instead

Теперь я хотел бы сделать то же самое в C ++

class A{
    int a;
public:
    A(int a) : a(a) {}
    bool operator<(A t){ return a < t.a; }
};

class B: public A{
    int b;
public:
    B(int a, int b) : A(a), b(b) {}
    bool operator<(B t){ return b < t.b; }
};

int main()
{
    A a(2);
    B b(3,1);

    std::cout << (a < b) << std::endl;
    //std::cout << (b < a); // error, A has no b attribute
    //std::cout << A::operator<(dynamic_cast<A&>(b),a); // basically what I would like to happen
    std::cout << a.operator<(dynamic_cast<A&>(b)) << std::endl; // here I would like to reverse a and b

    return 0;
}

Должен быть способ сделать это, я не знаю, просто ли этонедостаточное знание методов в C ++.

Я знаю, что вместо этого я мог бы просто перегрузить оператор> =, но это не главное, сравнение здесь только пример.

1 Ответ

0 голосов
/ 13 июня 2018

Отказ от ответственности: подобные вещи лучше никогда не делать в реальном коде, по крайней мере, для сравнения.Это просто пример использования некоторых конструкций C ++.

Вариант 1: статическая диспетчеризация.

class A{
    int a;
public:
    A(int a) : a(a) {}
    friend bool operator<(A& x, A& y){ return x.a < y.a; }
};

class B: public A{
    int b;
public:
    B(int a, int b) : A(a), b(b) {}
    friend bool operator<(B& x, B& y){ return x.b < y.b; }
};

Этот код сравнивает объекты A и B в соответствии с их типом static .Так что если у вас есть:

B b(0, 42);
A& a = b;

a будет вести себя как A в сравнениях.Система основана на перегрузке операторов.


Вариант 2: динамическая диспетчеризация.

class A;
class B;

class A{
    int a;
public:
    A(int a) : a(a) {}
    virtual ~A() {}
    bool operator<(A& t){ return t.compare(*this); }
protected:
    virtual bool compare (A& t);
    virtual bool compare (B& t);
};

class B: public A{
    int b;
public:
    B(int a, int b) : A(a), b(b) {}
protected:
    bool compare (A& t) override;
    bool compare (B& t) override;
};

bool A::compare(A& t) { return t.a < a; }
bool A::compare(B& t) { return t.a < a; }
bool B::compare(A& t) { return A::compare(t); }
bool B::compare(B& t) { return t.b < b; }

Этот код сравнивает объекты A и B в соответствии с их типом dynamic ,Так что если у вас есть:

B b(0, 42);
A& a = b;

a будет вести себя как B в сравнениях.Система основана на двойной динамической отправке, также известной как шаблон посетителей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...