我正在使用C ++简介,我遇到了涉及使用复制构造函数的问题。 练习的想法是构建一个Telephone对象,它本身构建一个Housing,Cable,Dialer和Headset。这一切都很有效,也很有启发性,因为每个类在调用时会给出一个cout,但是当我尝试以下内容时会出现问题。
Dialer构造了一个包含12个按钮的数组。 Buttons类看起来如下:
class Button {
public:
Button() { std::cout << "Button Constructor " << this << std::endl ; }
Button(const Button&) { std::cout << "Button Copy Constructor " << this << std::endl ; }
~Button() { std::cout << "Button Destructor " << this << std::endl ; }
private:
} ;
我在Dialer类中的第一个镜头使用按钮的静态分配,这很有效。代码:
class Dialer {
public:
Dialer() { std::cout << "Dialer Constructor " << this << std::endl ; }
Dialer(const Dialer &dialer) : buttons(dialer.buttons) { std::cout << "Dialer Copy Constructor " << this << std::endl ; }
~Dialer() { std::cout << "Dialer Destructor " << this << std::endl ; }
private:
Button buttons[12] ;
} ;
练习的下一步是动态分配按钮,以及乐趣开始的地方。以下代码可以使用:
class Dialer {
public:
Dialer() : buttons(new Button[12]) { std::cout << "Dialer Constructor " << this << std::endl ; }
Dialer(const Dialer &dialer) {
buttons = new Button[12];
std::cout << "Dialer Copy Constructor " << this << std::endl ;
}
~Dialer() {
delete[] buttons;
std::cout << "Dialer Destructor " << this << std::endl ;
}
private:
Button* buttons ;
} ;
但当然这并没有调用Button复制构造函数。我尝试过很多东西:
buttons = new Button(dialer.buttons)[12];
buttons = new Button(dialer.*buttons)[12];
*buttons = dialer.*buttons;
但我无法解决这个问题。所有这些尝试都会给出一个错误,即Button类中没有定义匹配函数。
我将不胜感激任何帮助:)
干杯, GeneralDuke
答案 0 :(得分:1)
以下代码段调用复制构造函数:
Button b;
Button a=b; // copy constructor called
或者您的阵列:
EDIT已更改为按值传递。
void addToArray(Button* arr, Button aButton, int idx)
{
arr[idx]=aButton;
}
buttons = new Button[12];
for (int i=0;i<12;i++)
{
addToButtons(buttons,dialer.buttons[i],i);
}
请注意,您在Button类上定义了复制构造函数,而不是在ArrayOfButtons类上定义。
编辑:添加依赖注入样本
我不认为你需要在Dialer + Button关系上使用复制构造函数,更像是Dialer + Phone关系。
以下是使用复制构造函数的示例(但它也需要修改后的构造函数):
class Dialer
{
public:
...
Dialer(Button& but):b(but){};
....
private:
Button b;
}
摘录:
{
Button b1;
Dialer d(b1);
}
对于12个按钮,在初始化时最终会使用12个参数。也许你应该坚持动态分配,而不是传递数组的值,并将复制构造函数用于其他类?
答案 1 :(得分:1)
以下代码格式调用复制构造函数。
Button a;
Button b=a; //calls the copy constructor of Button class
Button c;
c = a; // calls the overload assignment operator, but not the copy constructor.!
在您的情况下,对于实例数组,
buttons = new Button[12];
for (int i=0;i<12;i++)
{
buttons[i] = dialer.buttons[i];
}
答案 2 :(得分:1)
使用operator new[]
将使用他们的无参数构造函数构造那些Button
。使用=
进一步分配将调用赋值运算符。
如果您确实需要调用复制构造函数,则有三个选项:
首先,只使用std::vector<Button>
代替Button[12]
。这将处理您的分配和释放,并具有您想要的复制语义:
class Dialer {
public:
Dialer() : buttons(12) { std::cout << "Dialer Constructor " << this << std::endl ; }
Dialer(const Dialer &dialer) : buttons(dialer.buttons) {
std::cout << "Dialer Copy Constructor " << this << std::endl ;
}
~Dialer() { std::cout << "Dialer Destructor " << this << std::endl ; }
private:
std::vector<Button> buttons;
} ;
您的第二个选择是根据复制构造函数定义赋值运算符,通常称为复制和交换习语:
Button& operator= (Button other) { /*do swapping*/ }
您的第三个选择是使用std::allocator
分配内存并在单独的步骤中构建它,允许您调用复制构造函数来构造对象(注意,在实践中永远不要这样做; std::allocator
通常用于实现通用容器等,我只是在你的约束中显示一个解决方案):
class Dialer {
public:
Dialer() : buttons() {
std::allocator<Button> b_alloc;
buttons = b_alloc.allocate(12);
for (int i=0; i<12; i++)
{
b_alloc.construct(buttons+i); //this line requires C++11
}
std::cout << "Dialer Constructor " << this << std::endl ; }
Dialer(const Dialer &dialer) {
std::allocator<Button> b_alloc;
buttons = b_alloc.allocate(12);
for (int i=0; i<12; i++)
{
b_alloc.construct(buttons+i, dialer.buttons[i]);
}
std::cout << "Dialer Copy Constructor " << this << std::endl ;
}
~Dialer() {
std::allocator<Button> b_alloc;
for (int i=0; i<12; i++)
{
b_alloc.destroy(buttons+i);
}
b_alloc.deallocate(buttons, 12);
std::cout << "Dialer Destructor " << this << std::endl ;
}
private:
Button* buttons;
} ;