Я нашел проблему при использовании стороннего кода, который не может быть изменен. Мне нужно сделать копию члена объекта. Я не могу этого делать строго, потому что у одного из внутренних членов есть оператор частного назначения. Единственное решение, которое я нашел, сложно, поэтому я хочу спросить вас, видите ли вы какие-либо красные огни, которые могут повлиять на мою программу.Использование оператора размещения и нового оператора вместо оператора присваивания
Вот упрощенный код, который я имею дело с (помните, что я не могу изменить его!):
#include <iostream>
#include <algorithm>
class MBool
{
public:
MBool() {};
MBool(const MBool& arg) {}
private:
MBool& operator=(const MBool& arg);
};
class InnerContent {
private:
int* pBuffer;
public:
InnerContent() {
pBuffer = new int[20];
std::cout << "InnerContent()" << std::endl;
}
InnerContent(const InnerContent& otherInnerContent) {
pBuffer = new int[20];
std::copy(otherInnerContent.pBuffer, otherInnerContent.pBuffer + 20, pBuffer);
std::cout << "InnerContent(const InnerContent&)" << std::endl;
}
~InnerContent() {
std::cout << "~InnerContent()" << std::endl;
delete [] pBuffer;
pBuffer = nullptr;
}
virtual void someVirtualFunction() {}
};
class Content {
public:
InnerContent innerContent;
int someNumber;
MBool boolVar;
Content() {
std::cout << "Content()" << std::endl;
}
~Content() {
std::cout << "~Content()" << std::endl;
}
Content(const Content& otherContent) :
innerContent(otherContent.innerContent),
someNumber(otherContent.someNumber),
boolVar(otherContent.boolVar)
{
std::cout << "Content(const Content&)" << std::endl;
}
virtual void someVirtualFunction() {}
};
class A {
public:
Content content;
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
class B {
public:
Content content;
B() { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B()" << std::endl; }
};
И вот что я собираюсь делать с ним (только этот код может быть изменен и расширенный):
void copyContent(Content& contentFrom, Content& contentTo) {
contentTo.~Content();
new (&contentTo) Content(contentFrom);
};
int main() {
A a;
B b;
// I wish to do this:
//b.content = a.content;
// but Content class has no operator= function implemented
// also I can't use generated assignment operator function because of MBool::operator= is private
// The only work-around I found is this:
std::cout << "--- Before copying" << std::endl;
copyContent(a.content, b.content);
std::cout << "--- After copying" << std::endl;
}
Мое решением является вызов Content деструктора вручную освободить любую динамически выделенную память в содержании и его внутренние классы. Память в стеке остается нетронутой, поэтому я могу ее повторно использовать с оператором размещения-new, который вызывает конструктор копирования, который присутствует, и делает именно то, что мне нужно. Когда основная область функции заканчивается, объект «a» очищается должным образом.
выходКода:
InnerContent()
Content()
A()
InnerContent()
Content()
B()
--- Before copying
~Content()
~InnerContent()
InnerContent(const InnerContent&)
Content(const Content&)
--- After copying
~B()
~Content()
~InnerContent()
~A()
~Content()
~InnerContent()
Я не хочу, чтобы сделать свою собственную функцию, которая копирует все поля, так как этот класс может быть обновлена в новой версии и может быть дополнительным полем, которое я не буду копировать и скорее всего, никто не запомнит этого.
Вопрос: Как вы думаете, это может вызвать утечку памяти или повреждение памяти? Вы видите какие-то проблемы, о которых я не упоминал?
Вместо этого просто используйте интеллектуальный указатель на 'Content'. Легко заменить его указатель на новый. –
Я не вижу никаких проблем * per se *, просто убедитесь, что конструктор копий остается в курсе, или у вас будут проблемы ....... Я фактически использовал аналогичные стратегии для этого до – DarthRubik
Что происходит, когда вы do 'copyContent (x, x)'? – Barry