2013-07-23 3 views
0

У меня есть классы A, B. B происходит от A с защищенным, поэтому для включения неявного литья из B в A я добавил оператор литья, но я получаю ошибку при использовании его неявно (все в порядке при его использовании явно).Как определить неявный оператор литья

Как сделать этот код работой?

class A 
{ 
public: 
    int a; 
}; 


class B : protected A { 
public: 
    int b; 
    operator const A&()const { return *this; } 
}; 

B b; 
const A& a = b; // ERROR: error C2243: 'type cast' : conversion from 'const b *' to 'const A &' exists, but is inaccessible 

Как сделать литье неявным?

+1

Почему бы вам просто не сделать наследование публичным? – juanchopanza

+0

, потому что я хочу отключить некоторые функции от пользователя. Поэтому я разрешаю кастинг для ссылки const – bochaltura

+0

Что такое 'a &'? –

ответ

2

Обратный звонок, который вы предоставили уже неявный. Проблема, с которой вы сталкиваетесь, заключается в том, что компилятор видит две разные последовательности преобразований от B до const A&, ссылку на базовую ссылку и ваше пользовательское преобразование. Существует порядок заказов на конверсии, и преобразование с производной базой считается лучшим, чем любое преобразованное пользователем, поэтому ваш operator const A&() const не будет выбран.

Просто сделайте наследование общедоступным. Вы пытаетесь создать сложный дизайн, который не приносит никакой пользы. Что вы хотите получить, сделав наследование защищенным? Избегайте повышения? Почему вы все равно пытаетесь обеспечить такое же преобразование? Вы планируете использовать только половину интерфейса (часть const)? Тогда вы не следуете за LSP, так как ваш производный объект не может использоваться в качестве базы ...

+0

Важным моментом здесь является то, что все разрешения перегрузки происходят без учета доступа. Только после завершения разрешения перегрузки компилятор просматривает доступ и испускает ошибку, если выбранная функция недоступна. –

+0

@JamesKanze: Я не думаю, что здесь есть * разрешение перегрузки *. Это просто преобразование из lvalue в производную до ссылки const на базу. Кроме этого, комментарий справедлив: спецификаторы доступа всегда проверяются в конце, поэтому они не будут принимать решения относительно того, какой путь принять.- Ну, если быть точным в спецификациях доступа C++ 11 * может * управлять компилятором в контекстах SFINAE –

+1

Инициализация 'const A & a' фактически разрешается с помощью разрешения перегрузки, которое выбирает лучшую последовательность преобразования, чтобы получить от' b 'to' const A & '. Это не то, что типичный программист назвал бы перегрузкой, но стандарт не видит разницы (а также не компиляторов). –

0

Очевидно, оператор преобразования типов определен в B, поэтому он недоступен для объектов типа A. Что вы пытаетесь сделать это невозможно в C++. Это потому, что указатель «this» является постоянным указателем. Так что, если вы пытаетесь писать следующий код в теле, он не будет работать: A(B* b) { this = b;//error, 'this' pointer is a constant pointer. }

Другими словами, вы не можете неявно сделать ссылку типа А относятся к объекту типа B. В лучшем случае вы можете попробовать реинтерпретировать бросок и посмотреть, работает ли он.

0

OK - поэтому я выбрал другой дизайн - использовать композицию вместо наследования. Таким образом, я могу определить экземпляр A, который защищен

class B { 
protected: 
    A a; 
public 
    operator const A&()const { return a; } 
}; 

B b; 
const A& a = b; 
Смежные вопросы