С++ Diamond Inheritance - совместное использование переменных с другим небазовым классом

Это мой первый пост в stackoverflow, так что будьте осторожны :)

У меня стандартная проблема с бриллиантами, но мне удалось с ней разобраться.

class Control  
{ 
  public:  
    bool Focused;  
};

class Caption : public virtual Control  
{
  public:  
    string Text;  
};

class Frame : public virtual Control { };

class Textbox : public Caption, public Frame, public TextEditor { };

К сожалению, появилась еще одна проблема с наследованием. Класс TextEditor имеет общие имена переменных:

class TextEditor
{
  public:
    bool Focused;  
    string Text;  
};

Компилятор выдает мне ошибки:

неоднозначный доступ к "Текст"

неоднозначный доступ «Focused»

Но все, что я хочу, это объединить эти переменные из всех классов в производном классе Textbox.

Вот ссылка на изображение UML с проблемой

Спасибо за любую помощь. Извините за языковые ошибки и/или вопрос, который я задаю.

Обновить

Небольшое объяснение, потому что я мог использовать неправильные слова. Простите за это.

Под «слиянием» я имел в виду, что:

  • Если я использую переменные или методы Control, Caption или Frame, это повлияет на значения TextEditor и наоборот. Другими словами, переменные являются общими в производном классе.

Итак, мой последний класс будет выглядеть так:

class Textbox : public Caption, public Frame, public TextEditor  
{  
  public:   
    string Text;  
    bool Focused;  
};

А не так:

class Textbox : public Caption, public Frame, public TextEditor  
{  
  public:   
    string Caption::Text;   
    bool Caption::Focused;  
    string TextEditor::Text;  
    bool TextEditor::Focused;  
};

Что происходит прямо сейчас. Потому что я не могу сделать это:

Textbox A;
A.Text = "Text";

Потому что у меня есть две переменные с именем Text. Итак, я должен был бы сделать это:

Textbox A;
A.Caption::Text = "Text";
A.TextEditor::Text = "Text";

С уважением Лави Полезно Бесполезно


person Lavi    schedule 15.07.2013    source источник
comment
Прочтите stackoverflow.com/help/how-to-ask.   -  person Mgetz    schedule 15.07.2013
comment
Какой пункт «как спросить» я нарушил? Вопрос конкретный. Я узнал через Интернет об этой проблеме, что еще?   -  person Lavi    schedule 15.07.2013
comment
возможный дубликат неоднозначного наследования класса   -  person Mgetz    schedule 15.07.2013
comment
Как вы хотите, чтобы эти переменные были объединены? Когда вы ссылаетесь на переменную Text в методе Textbox, какой из них должен использовать компилятор? Они не могут быть просто объединены, так как TextEditor::Text используется для чего-то другого, чем Caption::Text. Если бы вы объединили эти переменные, методы Caption могли бы повлиять на значение TextEditor::Text   -  person Alexander Weinert    schedule 15.07.2013
comment
@Mgetz - проблема с бриллиантами в моем случае уже решена. Я сказал это в своем вопросе. Эту проблему можно рассматривать как расширение той проблемы   -  person Lavi    schedule 15.07.2013
comment
@Alexander Weinert - это именно то, что я хочу :)   -  person Lavi    schedule 15.07.2013
comment
@Lavi, пожалуйста, ознакомьтесь с meta.stackexchange.com/questions/100278/ также tinyurl.com/so-hints   -  person Mgetz    schedule 15.07.2013
comment
Я проголосовал, но вы должны улучшить свой вопрос. Я читал много раз, но до сих пор не совсем понимаю, что вы хотите делать с этими переменными.   -  person khajvah    schedule 15.07.2013
comment
@khajvah Проблема может быть в слове, которое я использовал «объединить». Я хочу добиться того, о чем сказал «Александр Вейнерт» в конце своего комментария. Если я использую переменные, методы Caption повлияют на значения TextEditor.   -  person Lavi    schedule 15.07.2013
comment
@Lavi, похоже, вы нашли, как исправить свой вопрос, ясность имеет большое значение, равно как и демонстрация того, какого поведения вы намереваетесь достичь и что вы пробовали ранее. Не бойтесь многословия. Руководство, на которое я ссылался ранее, действительно является хорошим способом задать вопрос.   -  person Mgetz    schedule 15.07.2013
comment
@Mgetz Но иногда вам может не хватать правильных слов, особенно если вы не являетесь носителем английского языка или не знаете слов, которые следует использовать. Спасибо :)   -  person Lavi    schedule 15.07.2013


Ответы (1)


Заметки:

  1. Попробуйте использовать методы-мутаторы.
  2. Пожалуйста, http://sscce.org/ - ваш пример кажется немного чрезмерным - было бы проще дать вам наглядный пример того, как решить вашу проблему, если ваш пример в проблеме был на самом деле sscce. В любом случае, этого все еще достаточно, и ваша проблема достаточно ясна, я думаю.

Ответы:

  1. Почему class TextEditor не наследуется также от class Control и class Caption? Казалось бы, это очевидное решение - вам все равно придется использовать виртуальное наследование для class TextBox.
  2. Если 1 не вариант, то есть это, но в этом ограниченном примере HasText и Focusable кажутся бессмысленными по сравнению с Caption и Control соответственно.

    class HasText
    {   
    public:
        virtual string& text() { return text; }
        virtual const string& text() const { return text; }
    private:
        text
    };  
    
    class Focusable
    {   
    public:
        virtual bool& focused() { return focused; }
        virtual const bool& focussed() const { return focussed; }
    };  
    
    class Control : public virtual Focusable { };
    
    class Caption : public virtual Control, public virtual HasText { };
    
    class Frame : public virtual Control { };
    
    class TextEditor : public virtual HasText, public virtual Focusable { };
    
    class Textbox : public virtual Caption, public virtual Frame, public virtual TextEditor { };
    
person Iwan Aucamp    schedule 15.07.2013
comment
Второй вариант потребует от меня перепроектировать весь GUI API. В моем случае первый вариант также не мог быть использован. Так что единственное, что я могу сделать, это дублировать код TextEditor, разобрать его на части, чтобы он мог наследовать Caption. Я хотел избежать этого, но иногда нужно сделать шаг назад, чтобы двигаться вперед. В любом случае спасибо за идеи и помощь :) - person Lavi; 16.07.2013
comment
Если бы вы использовали методы мутатора, это также могло бы предоставить возможность. - person Iwan Aucamp; 16.07.2013