Не могли бы вы расширить:
Теперь это работает само по себе, но когда в картину приходит наследование, у меня возникают проблемы
Вы имеете в виду множественное наследование двух базовых классов, каждый из которых наследуется от вашего класса SmartDefs? Вы имеете в виду наследование как от класса SmartDefs, так и от базового класса, который сам наследуется от класса SmartDefs?
В любом случае, ваша проблема, конечно, не в C ++ 0x, а в общей неоднозначности базовых членов.
Пример:
#include <iostream>
struct A
{
typedef int ret_type;
static ret_type go(){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct B
{
typedef int ret_type;
static ret_type go(){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct C : public A, public B
{
typedef int ret_type;
static ret_type go(){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
int main()
{
C c;
C::A::ret_type ago = c.A::go();
C::B::ret_type bgo = c.B::go();
C::ret_type cgo = c.go();
C::A::ret_type static_ago = C::A::go();
C::B::ret_type static_bgo = C::B::go();
C::ret_type static_cgo = C::go();
}
Итак, вам нужно решить проблему таким же образом: явное устранение неоднозначности во время вызова или, предпочтительно, перегрузка функций / typedefs в вашем производном классе.
Однако я не уверен, что рекомендую ваше решение вообще. Перед лицом наследования Derived::unique()
вернул бы unique_ptr<Base>
, если Derived не наследовал от вашего класса SmartPtr. Единственный «безопасный» способ реализовать нечто подобное - использовать виртуальную функцию Create () (в вашем случае: возможно, CreateUnique, CreateShared).
Я бы лично предпочел написать глобальный make_shared
для переноса std::make_shared
и написать свой make_unique
в том же пространстве имен.
A::shared() // replace
make_shared<A>() // with this
A::unique() // replace
make_unique<A>() // with this
Разница в несколько символов здесь тривиальна по сравнению с тем, что не нужно наследовать каждый класс от SmartDefs и избежать большого риска неправильного использования.
Редактировать: Я забыл упомянуть, что вы потеряете typedef для возвращаемого типа таким образом. Вы можете использовать type_traits, но я на самом деле считаю, что отсутствие typedef здесь есть функция. Информацию о базовых классах aboyt, таких как std :: shared_ptr и std :: unique_ptr, не нужно удалять с помощью typedef, а между auto
, templates и decltype
не требуется явных typedefs.