Почему переменная-член x неоднозначна? - PullRequest
4 голосов
/ 25 января 2020

Может кто-нибудь объяснить мне следующую ошибку компилятора, которая говорит, что 'x' является неоднозначной ссылкой?

Почему компилятор не может этого допустить, если он знает, что одна из этих переменных на самом деле недоступна?

class A {
    int x; // private here
};

class B {
public:
int x; // public here
};

class C : public A, public B {

};

int main() {

    C c;
    c.x = 5; // here is the error

    return 0;
}

Редактировать: Для людей, которые объясняют мне, что частное не означает, что оно не может быть изменено - я знаю это, и сделал этот простой пример ниже, но это не тот случай, о котором я спрашивал.

//
// the goal is to hack x, y values
//
#include <stdio.h>
#include <memory>

class A {
    int x;
    int _r;
    double y;
public:
    A() { x = 1; y = 0.5; _r = 0; }
    void foo() { printf("x = %d, y = %lf, _r = %d\n", x, y, _r); }
};

int main() {

    struct _B {
        int x = 2;
        double y = 1.5;
    } b;

    A a;

    a.foo();    // gives "x = 1, y = 0.500000, _r = 0"
    memcpy(&a, &b, sizeof(_B)); // where the sizeof B is eq 16 (4 for int, 4 for padding, 8 for double)
    memcpy(&a, &b, sizeof(b.x) + sizeof(b.y)); // that is undefined behaviour, in this case _r is overridden
    a.foo();    // gives "x = 2, y = 1.500000, _r = -858993460" (_r is just a part of floating point y value but with invalid cast)

    return 0;
}

1 Ответ

4 голосов
/ 25 января 2020

Ваш C содержит две x переменные. Один унаследован от каждого родительского класса. Поэтому неоднозначно, хотите ли вы присвоить A::x или B::x. Тот факт, что один из них недоступен, не означает, что другой будет выбран автоматически. Компилятор не может знать, если вы намеревались попытаться присвоить частному A::x (что тогда было бы другой ошибкой) или общедоступной c B::x.

Кроме того, как отмечено в комментариях, class C : public A,B является , а не таким же, как class C : public A, public B. В первом случае вы наследуете публично от A, но приватно от B (поскольку частное наследование является значением по умолчанию для class в отличие от struct, где по умолчанию используется публичное c наследование). Во втором случае вы бы унаследовали публично от обоих базовых классов.

...