2013-09-02 8 views
2

В C++/C++ 11, как я могу получить ссылку/указатель на «владельца» экземпляра вложенного класса? Например:Владелец объекта вложенного класса

class A 
{ 
public: 
    friend class B; 
    class B 
    { 
    public: 
     Foo bar(int i) { return get_owner().x[...]; } 

    private: 
     A& get_owner() 
     { // How to do this? Pseudo code: 
      return (A*)(this - offsetof(A, b)); 
     } 
    }; 

    B b; 
}; 

Примечание: В моем случае, А неstandard layout type, потому что она имеет частные и публичные переменные-члены.

фона: Я хотел бы реализовать «нулевой стоимости» синтаксически сложных свойств, доступ к структурам данных в имущего класса и которые позволяют пользователям А писать, например,

A a; 
... 
x = a.nodes[5]; 
y = a.nodes.size(); 
for (auto n: a.nodes) // using a.nodes.begin() and a.nodes.end() 
    ... 

Примечание 2: Я, вероятно, мог бы сделать это, используя грязные трюки, но есть ли переносимый, совместимый со стандартами способ сделать это?
Если нет, мне придется реализовать B, чтобы я мог написать «a.nodes (5)» и «for (auto n: a.nodes())», но это выглядит довольно уродливо.

Редактировать: Я уже думал о том, чтобы дать B ссылку на A, но тогда я не мог использовать оператор-конструктор/присваивание по умолчанию для оператора A. Это было бы не так плохо в моем случае, Любопытно, есть ли другое решение.

+3

Я боюсь объявить вложенный класс, не делает того, что, по вашему мнению, делает. –

+1

Классы, определенные одним внутри другого, не имеют между ними отношения. Это почти то же самое, что и класс внутри пространства имен. – user1233963

+3

Вы не можете сделать это на C++, потому что классы, вложенные в другие классы, не имеют ссылок на их внешние классы. Внешний класс для внутреннего класса скорее является пространством имен, чем владельцем. – dasblinkenlight

ответ

3

Добавить участника в B, что указывает на владельца.

+0

Это не будет «нулевая стоимость», которую хочет OP –

+0

@ArneMertz Правда, но такого решения с нулевой стоимостью не существует. – Angew

+0

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

0

Тот факт, что каждый экземпляр класса A имеет член класса B, не относится к классу B.

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

Нет, если вы не скажете об этом, конечно. И это потребует хранения в-B -объекта; B должен будет сохранить указатель/ссылку на A, членом которого он является.

фона: Я хотел бы реализовать «нулевой стоимости» синтаксически сложных свойств, доступ к структурам данных в имущего класса и которые позволяют пользователям А писать, например,

Это невозможно в C++; лучше отказаться от него сейчас. Даже если B были пустым, нет необходимости, чтобы они не занимали место в A. Действительно, есть требование, чтобы они : занимают место в A. Каждый член экземпляра класса имеет адрес, и ни один из двух членов не может иметь тот же адрес. Оптимизация с пустым основанием работает только для базовых классов , а не для членов.

Так что «нулевая стоимость» невозможна. Поскольку B экземпляры должны занимать место в A, вы можете также использовать это пространство для удобства использования, указав указатель/ссылку на элемент A.

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