2011-01-12 2 views
9

Я использую личное наследование в проекте, в «реализованном в терминах» -чувствительности. Базовый класс определяет оператор [], и это функциональность, которую я хочу использовать. Таким образом, у меня естьЧастное наследование с использованием директивы, перегрузок?

class A : private B { 
    using B::operator[]; 
    // ... 
}; 

Однако, как я могу контролировать, какую версию оператора [] я получаю? На самом деле мне нужно больше одного, как версии const, так и не const. Можно ли это сделать?

+3

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

+1

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

+0

Ваш код будет намного проще писать и поддерживать, если вы используете композицию вместо частного наследования. Эмпирическое правило заключается в том, чтобы не использовать внеуровневые функции C++, когда они не являются абсолютно необходимыми (из того, что вы сказали до сих пор, частное наследование в этом случае не требуется). –

ответ

6

Я понимаю, что ваш using должен автоматически вводить все различные перегрузки оператора. Существуют ли определенные перегрузки, которые вы хотите исключить из того, чтобы быть вовлеченными в дочерний класс? В этом случае было бы лучше разделить работу на несколько именованных функций в родительском и только using те, которые вам нужны.

+0

Я бы тоже так подумал, но я получаю ошибки компиляции из const-discarding, несмотря на то, что существуют версии, возвращающие как 'T &', так и 'const T &' (template typename T) – carlpett

+0

Итак, это один из них «волшебным образом исправлен» «раз ... Посмотрев вверх и вниз по коду и перекомпиляции, он внезапно работает, и я не могу, чтобы жизнь меня поняла, что я изменил. Что изменилось, хотя я узнал немного больше о наследовании, так что спасибо! – carlpett

2

Это делает, как и ожидалось:

class A 
{ 
public: 
    int operator[](int idx) { return 0; } 
    int operator[](int idx) const { return 1; } 
}; 

class B : public A 
{ 
public: 
    using A::operator[]; 

    void opa() { cout << operator[](1) << endl; } 
    void opb() const { cout << operator[](1) << endl; } 
}; 

int main(void) 
{ 
    B b; 
    b.opa(); 
    b.opb(); 

    const B d = B(); 
    cout << d[1] << endl; // should trigger the const version of operator[] 
    return 0; 
} 

Другими словами, соответствующие константные/не константные версии вводятся в B. ПРИМЕЧАНИЕ. Если версия const не указана, вы получите ошибку компилятора (это работает, является ли наследование закрытым или общедоступным).

+0

Спасибо, хороший пример! – carlpett

+0

Я бы также добавил 'b [2];' или похоже на 'main', чтобы показать, что операционные функции могут использоваться непосредственно извне' class B'. – aschepler

+0

@aschepler, хорошая точка, будет обновляться ... – Nim

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