2010-10-16 3 views
5

Редактировать - Поместите вопрос в контекст немного больше.литые Производные * const на базу * const

Дано:

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 не имеет смысла для меня, поскольку я не хочу, чтобы изменить константность, и я не изменить то, что я указываю на, так почему же тогда г ++ сказать мне

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

? Если я откажусь от литья, в нем будет указано:

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

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

+0

Если 'Derived' на самом деле имеет' Base' в качестве базового класса, то (a) этот код не должен вызывать никаких ошибок (это может вызвать предупреждение о том, что определитель const в target_ static_cast не делает ничего) и (b) вы можете просто назначить '_derived_ptr'' _base_ptr', как предлагает Оли. –

+0

Я думаю, что у вас есть константа с другой стороны: 'Base * const x;' Здесь x является указателем const на 'standard Base' (т. Е. Вы не можете изменить x). 'Base const * x' Здесь x является указателем на' const Base' (т. Е. Objext, на который указывает x, является const). –

+0

У меня на самом деле есть указатели как const, а не объекты, на которые указывает. Кроме того, этот вопрос не является полностью _точным (просто чтобы я не наполнил вопрос кодом), потому что я использую статический приведение в конструкторе, вызывающий его родительский конструктор: 'SomeClass :: SomeClass (Derived * const _d): SomeBase (static_cast (_d)) {} ' – parallel

ответ

5

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

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

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

1

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

+0

Никакая трансляция не говорит мне «никакой подходящей функции для вызова« Алиса »(Derived * const &) '' – parallel

+1

@parallel: вы неявно объявили свои конструкторы частными, поэтому 'Bob' не может видеть' Alice :: Alice (Base *) '. В стороне, noe, что вам не нужно 'const' в этом контексте (т. Е. Прототипы функций). –

+0

Компилятор должен уметь * видеть * его. Контроль доступа не влияет на видимость. Тем не менее, компилятор не сможет * получить доступ к нему. В подобных случаях сообщение об ошибке обычно выглядит по-разному. Я подозреваю, что код подделка. – AnT

1

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

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

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

?
Возможно, вы забыли публикацию? Просто теория ...

+0

Я думаю, что скорее всего 'Derived' и' Base' являются просто несвязанными типами. –

+0

Это производная общественность. – parallel

+0

Derived объявлен как: 'struct Derived: public Base {...};' – parallel

0

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

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

Приветствия & HTH.,

+0

Да, скорее всего, он это делает, но все же это тайна ... –

+0

Я намеревался, чтобы указатели были const, а не объекты, на которые указывает. – parallel

+0

@parallel: Обычно не имеет смысла объявлять функции, которые принимают константные параметры, поскольку они эквивалентны как declarat ионам тех, кто принимает без const. Единственное различие заключается в определении, в котором вы не можете изменить параметр –

1

компилируется отлично на г ++ 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; 
} 
+0

Кроме того, я бы рекомендовал вам использовать dynamic_cast в таких случаях, окружить бросок в блоке try-catch и проверить, не возвращается ли возвращаемое значение NULL. Кстати, вам действительно не нужны какие-либо роли. –

+1

'dynamic_cast' совершенно не имеет смысла здесь вообще. Во-первых, нет необходимости в каких-либо актерах. Во-вторых, цель 'dynamic_cast' должна использоваться для downcasts и cross-cast. Это * upcast *. Нет существенной причины использовать 'dynamic_cast' для upcasts. – AnT

+0

Хорошо, отмечено для static_cast и dynamic_cast. Я не знал об этом, спасибо (: –

0

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

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

У вас есть static_cast, за исключением избыточного квалификатора const в целевом типе. То, что const просто не имеет смысла, но это не ошибка.

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

0

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

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

+0

Я намеревался, чтобы указатели были const, а не объекты, на которые указывает. – parallel

 Смежные вопросы

  • Нет связанных вопросов^_^