приведение Производное * const к базе * const - PullRequest
5 голосов
/ 17 октября 2010

Редактировать - поставить вопрос в контекст немного больше.

Дано:

struct Base
{
    ...
};
struct Derived : public Base
{
    ...
};
class Alice
{
    Alice(Base *const _a);
    ...
};
class Bob : public Alice
{
    Bob(Derived *const _a);
    ...
};

Когда я пытаюсь реализовать

Bob::Bob(Derived *const _d) : Alice(static_cast<Base*const>(_d)) { }

это не работает. const_cast не имеет смысла для меня, так как я не хочу менять константность, и я не изменяю то, на что я указываю, так почему же g ++ говорит мне

invalid static_cast from type ‘Derived* const’ to type ‘Base* const’

? Если я опущу актерский состав, он говорит

no matching function for call to ‘Alice::Alice(Derived* const)’

Если бы кто-нибудь мог пролить свет на это, это было бы очень ценно.

Ответы [ 7 ]

5 голосов
/ 17 октября 2010

Проблема заключалась в том, что Derived был неполным типом, т.е. объявлен форвард.Боюсь, что я всех переживаю :( Ответ появился, когда Кирилл Кироу предложил использовать динамическое приведение, из-за которого g ++ выплюнул немного более полезную ошибку:

error: cannot dynamic_cast ‘_d’ (of type ‘struct Derived* const’) to type ‘struct Base* const’ (source is a pointer to incomplete type)

К сожалениюЯ заранее объявил Derived, но я не понял, что это актуально, и он был спрятан на несколько заголовков ниже, что заставило бы меня публиковать здесь слишком много кода. Извините всех, но я надеюсь, что это поможет кому-то еще позже.

1 голос
/ 17 октября 2010

Прекрасно компилируется на g ++ 4.4.3, нет даже предупреждений:

#include <iostream>

struct Base
{
    Base()
    {
    }
};

struct Derived : public Base
{
    Derived() {}
};

class Alice
{
public:
    Alice( Base *const _a )
    {
        std::cout << "Alice::Alice" << std::endl;
    }
};

class Bob : public Alice
{
public:
    Bob(Derived *const _a) 
        : Alice( static_cast< Base * const >( _a ) )
    {
        std::cout << "Bob::Bob" << std::endl;
    }
};

int main()
{
    Derived* pDer = new Derived();
    Bob b( pDer );
    return 0;
}
1 голос
/ 17 октября 2010

У меня есть теория. Что если во время деривации вы случайно забыли указать, что деривация является публичной? В этом случае он будет закрытым по умолчанию и указанное преобразование будет недоступно.

Вы уверены, что написали

class Derived : ***public*** Base {...}


Или, может быть, вы забыли публику? Просто теория ...

1 голос
/ 17 октября 2010

Тебе вообще не нужен каст.У вас есть константные указатели, а не указатели на константные объекты.И допустимо присваивать адрес производного объекта указателю на базу без приведения.

0 голосов
/ 17 октября 2010

Хотя я не уверен (слишком мало контекста), я думаю, вы могли иметь в виду Базовая константа * и Производная константа *.

Базовая константа* - указатель на постоянный базовый объект. Base * const - постоянный указатель на модифицируемый базовый объект.

0 голосов
/ 17 октября 2010

Единственная проблема здесь в том, что Alice::Alice является приватным в Alice.Bob не имеет доступа к Alice::Alice.

С приведением типов проблем нет.На самом деле, вам не нужно static_cast для этого.Он должен быть конвертирован неявно.

Действующий в настоящее время static_cast действителен, за исключением избыточного квалификатора const в целевом типе.То, что const там просто не имеет смысла, но это не ошибка.

Почему ваш компилятор выдает эти странные сообщения об ошибках, мне не ясно.Я подозреваю, что код, который вы разместили, является поддельным.

0 голосов
/ 17 октября 2010

У вас есть несвязанные типы Alice и Base.Измените конструктор Alice, чтобы взять Base*.

Кстати, я подозреваю , что у вас неправильно введены const места размещения.

Приветствия и hth.,

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