【C++言語入門】 第16回 コピーコンストラクタ
メンバ変数をそのままコピーします
#include <iostream>
struct fruit {
int weight;
int price;
};
int main(int argc, char* argv[]) {
fruit apple = {100, 200};
fruit pomme = apple;
apple.weight = 150;
std::cout << "リンゴの重さは" << pomme.weight << "gです。" << std::endl;
std::cout << "リンゴの値段は" << pomme.price << "円です。" << std::endl;
return 0;
}
fruit pomme = apple;
の部分でコピーしていますわ
fruit& pomme = apple;
のように 参照 であれば、"pomme.weight"も150に変わっているはずですわ
#include <iostream>
struct fruit {
int weight;
int price;
};
int main(int argc, char* argv[]) {
fruit apple = {100, 200};
fruit& pomme = apple;
apple.weight = 150;
std::cout << "リンゴの重さは" << pomme.weight << "gです。" << std::endl;
std::cout << "リンゴの値段は" << pomme.price << "円です。" << std::endl;
return 0;
}
#pragma once
#ifndef CIRCLE_H
#define CIRCLE_H
#include <iostream>
const double kPI = 3.14159265358979323846;
/// @brief 円
class Circle {
double diameter_; // 直径
public:
Circle() : Circle(0.0) {}
Circle(double diameter) : diameter_(diameter) {
}
virtual ~Circle() {
};
double Diameter() { return diameter_; }
void Diameter(double diameter) { diameter_ = diameter; }
virtual double Area() {
double radius = Diameter() / 2.0;
double a = radius * radius * kPI;
return a;
}
};
#endif // CIRCLE_H
#include <iostream>
#include "circle.h"
int main(int argc, char* argv[]) {
Circle c(10.0);
Circle c0 = c;
std::cout << "円の直径は" << c0.Diameter() << "cmです。" << std::endl;
std::cout << "円の面積は" << c0.Area() << "cm^2です。" << std::endl;
return 0;
}
Circle
クラスのメンバ変数として文字列を持たせてみましょう
#pragma once
#ifndef CIRCLE_H
#define CIRCLE_H
#include <iostream>
const double kPI = 3.14159265358979323846;
const int kMessageSize = 50;
/// @brief 円
class Circle {
double diameter_; // 直径
char* pmessage_;
public:
Circle() : Circle(0.0) {}
Circle(double diameter) : diameter_(diameter), pmessage_(nullptr) {
pmessage_ = new char[kMessageSize];
}
virtual ~Circle() {
delete[] pmessage_;
pmessage_ = nullptr;
};
double Diameter() { return diameter_; }
void Diameter(double diameter) { diameter_ = diameter; }
virtual double Area() {
double radius = Diameter() / 2.0;
double a = radius * radius * kPI;
return a;
}
virtual const char* Message() {
double area = Area();
sprintf_s(pmessage_, kMessageSize, "円の面積は%fです。", area);
return pmessage_;
}
};
#endif // CIRCLE_H
#include <iostream>
#include "circle.h"
int main(int argc, char* argv[]) {
Circle c(10.0);
Circle c0 = c;
std::cout << "円の直径は" << c0.Diameter() << "cmです。" << std::endl;
std::cout << c0.Message() << std::endl;
return 0;
}
Circle
クラスのインスタンスc0
とc
は別のものですが、各メンバ変数はコピーされたものですわ
コピーコンストラクタで解消しましょう
new
などで動的にメモリを確保して割り当てた場合には、単純なコピーでは不具合が生じるのだ
クラス インスタンス名 = 別のインスタンス;
という形式でクラスのインスタンスを生成、初期化する際に呼ばれる、特別なコンストラクタですわ
クラス名(const クラス& 引数名) : 初期化子リスト {
処理
}
memcpy
などを使用してコピーしておきますわ
Circle
クラスに コピーコンストラクタ を追加してみましょう
#pragma once
#ifndef CIRCLE_H
#define CIRCLE_H
#include <iostream>
const double kPI = 3.14159265358979323846;
const int kMessageSize = 50;
/// @brief 円
class Circle {
double diameter_; // 直径
char* pmessage_;
public:
Circle() : Circle(0.0) {}
Circle(double diameter) : diameter_(diameter) {
pmessage_ = new char[kMessageSize];
}
Circle(const Circle& c) : Circle(c.diameter_) {
memcpy_s(pmessage_, kMessageSize, c.pmessage_, kMessageSize);
}
virtual ~Circle() {
delete[] pmessage_;
pmessage_ = nullptr;
};
double Diameter() { return diameter_; }
void Diameter(double diameter) { diameter_ = diameter; }
virtual double Area() {
double radius = Diameter() / 2.0;
double a = radius * radius * kPI;
return a;
}
virtual const char* Message() {
double area = Area();
sprintf_s(pmessage_, kMessageSize, "円の面積は%fです。", area);
return pmessage_;
}
};
#endif // CIRCLE_H
Circle(const Circle& c)
の部分が コピーコンストラクタ なのだ
Circle(c.diameter_)
を指定して通常のコンストラクタを呼び出していますわ
memcpy_s
を使ってコピーしていますわ
Circle c0 = c;
の代わりにCircle c0(c);
としてはダメなのか?
Discussion