使用不能更改的第三方代碼時發現問題。我需要製作一個對象成員的副本。我不能嚴格這樣做,因爲內部成員之一有私人分配操作員。我發現的唯一解決方案很棘手,所以我想問你是否看到任何可能影響我的程序的紅燈。使用placement-new操作符和複製構造函數而不是賦值操作符
這裏是我處理的簡化的代碼(記得我不能改變它!):
#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;
}
我的解決辦法是手動調用內容析構函數,以釋放在內容中的任何動態分配的存儲器並且其內的類。內存堆棧保持不變,所以我可以重複使用放置新運算符調用目前的拷貝構造函數,並且完全符合我的需要。當主要功能範圍結束時,'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'。易於用新的替代它的指針。 –
我沒有看到任何問題*本身*,只是確保複製構造函數保持最新,否則您將遇到問題.......我實際上在此之前使用了類似的策略 – DarthRubik
當你做'copyContent(x,x)'? – Barry