J>А что за задача возникла, что такое понадобилось?
Для чего это может быть нужно?
Пусть есть классы Фу и Бар, причем классу Бар для работы нужно обращаться к объекту класса Фу. Естественное решение — иметь внутри класса Бар ссылку на объект Фу:
class Foo {
public:
void Do() {}
};
class Bar1 {
public:
Bar1(Foo &foo)
: m_foo(foo) {}
public:
void Do() { m_foo.Do(); }
private:
Foo &m_foo;
};
Поскольку Бар должен работать в содружестве с Фу, то естественно сделать класс-оболочку Фубар, который будет содержать в себе и Фу, и Бар:
class Foobar1 {
public:
Foobar1()
: m_bar(m_foo) {}
public:
void Do() { m_bar.Do(); }
private:
Foo m_foo;
Bar1 m_bar;
};
А теперь подумаем. Зачем m_bar содержит в себе ссылку на лежащий рядом с ним m_foo?
Ведь m_bar знает указатель на себя (свой
this), а компилятор знает смещение между m_foo и m_bar. То есть, m_bar может вычислить указатель на m_foo, и хранить его не нужно.
Так что, если предполагается, что Фу и Бар всегда будут использоваться в составе некой Фубар-оболочки, то, теоретически можно было бы выкинуть из Бара ссылку на Фу, заменить ее этакой compile-time ссылкой.
Что-то вроде того:
template <typename FOOBAR>
class Bar2 {
public:
void Do() { RetrieveFoo().Do(); }
private:
Foo& RetrieveFoo() { return member_cast<FOOBAR&>(*this).m_foo; }
};
class Foobar2 {
public:
void Do() { m_bar.Do(); }
private:
Foo m_foo;
Bar2<Foobar2> m_bar;
};
Отмечу также еще пару достоинств такого подхода.
У Foobar1 есть явные проблемы с копируемостью. У Foobar2 их нет.
У Bar2 и Foobar2 нет дурацких конструкторов, которые были у Bar1 и Foobar1