Предположим, я пишу класс, который можно было бы повторно использовать в различных контекстах. Его конструктор принимает определенный пользователем тип, который я храню в переменной-члене. Даже для объектов, которые, как мне известно, дешевы для копирования, я пытаюсь решить, лучше ли принимать аргумент по значению или указателем.Должен ли я хранить аргумент конструктора по значению или указателем?
// By value
class MyType
{
private:
SomeUdt udt_;
public:
MyType(SomeUdt udt) :
udt_ {udt}
{}
// ...
};
против
// By pointer
class MyType
{
private:
std::shared_ptr<SomeUdt> udt_;
public:
MyType(std::shared_ptr<SomeUdt> udt) :
udt_ {udt}
{}
// ...
};
Если я его (общий) указатель, то я почти наверняка заставляя клиента выделить этот объект в куче. (Технически они могли бы выделить в стеке и все еще послать мне указатель, но это было бы замутить собственности и жизни.)
И если я возьму его значение, то я удалю их способность управлять экземплярами, например, если клиент хотел, чтобы SomeUdt был синглом.
Каков наилучший подход по умолчанию?
EDIT:
Пару других интересных моментов в этом анализе.
Во-первых, комментатор отметил, что если я возьму по указателю, то мои личные данные не будут полностью закрытыми. Клиент имеет доступ к моему объекту-члену.
Кроме того, если пользовательский тип должен быть полиморфным и иметь любые чистые виртуальные элементы, то, я думаю, у вас нет выбора, кроме как использовать указатели.
Если вы передадите его в качестве указателя, клиент может изменить личную переменную через этот указатель. – kvorobiev
по значению - затем переместите его на место. –
Что не так с шаблоном Явный MyType (Us && ... Vs): udt_ (std :: forward (Vs) ...) {} 'Является ли ваш контейнер шаблоном? Если это шаблон, сохраните его по значению, а _client_ может создавать экземпляр с указателем, если это то, что они хотят: 'MyType >'. Зачем нужен этот объект? –