板凳——————————————————c++(9)

//2020年04月27日 20时48分13秒
// Professional c++ 4th Edition P 155-p165
#include
#include
#include “SpreadsheetCell.cpp”
#include
#include
#include
#include
class Spreadsheet
{
public:
Spreadsheet(size_t width, size_t height);
Spreadsheet(const Spreadsheet& src) ;
Spreadsheet(Spreadsheet&& src) noexcept;// no const
~Spreadsheet();

    Spreadsheet& operator=(Spreadsheet&& rhs) noexcept;// no const
Spreadsheet& operator=(const Spreadsheet& rhs) ;
//只想禁止其他人复制对象或者为对象赋值, 只需显示地加 delete
//Spreadsheet(const Spreadsheet& src) = delete;
    //Spreadsheet& operator=(const Spreadsheet& rhs) = delete;
void setCellAt(size_t x, size_t y, const SpreadsheetCell& cell);
SpreadsheetCell& getCellAt(size_t x, size_t y);

friend void swap(Spreadsheet& first, Spreadsheet& second) noexcept;

private:
std::string mName;
void cleanup() noexcept;
void moveFrom(Spreadsheet& src) noexcept;
void verifyCoordinate(size_t x, size_t y) const;
Spreadsheet() = default;
size_t mWidth = 0;
size_t mHeight = 0;
//SpreadsheetCell** 原因是Spreadsheet对象的尺度可能不同, 类的构造函数必须根据客户指定的宽度和高度
//动态分配二维数组。
SpreadsheetCell** mCells = nullptr;
};

void Spreadsheet::cleanup() noexcept{
for(size_t i = 0; i < mWidth; i++ ){
delete[] mCells[i];
}
delete[] mCells;
mCells = nullptr;
mWidth = mHeight = 0;
}

void Spreadsheet::moveFrom(Spreadsheet& src) noexcept{
//move object data members
mName = std::move(src.mName);
//move primitives原始的, 落后的, //shallow copy of data
mWidth = src.mWidth;
mHeight = src.mHeight;
mCells = src.mCells;
//reset the source object, because ownership has been moved!
src.mWidth = 0;
src.mHeight = 0;
src.mCells = nullptr;
}

Spreadsheet::Spreadsheet(Spreadsheet&& src) noexcept
{
std::cout << “Move constructor” << std::endl;
moveFrom(src);
}

Spreadsheet& Spreadsheet::operator = (const Spreadsheet& rhs) {
std::cout << "Copy assignment operator " << std::endl;
if(this == & rhs){
return *this;
}
// Copy-and-swap idiom
Spreadsheet temp(rhs); // Do all the work in a temporary instance
swap(*this, temp); // Commit the work with only non-throwing operations
return *this;
}

//Spreadsheet::Spreadsheet(Spreadsheet&& src) noexcept{
// moveFrom(src);
//}

Spreadsheet& Spreadsheet::operator = (Spreadsheet&& rhs) noexcept{
if(this == &rhs){
return *this;
}
cleanup();
moveFrom(rhs);
return *this;
}

Spreadsheet createObject(){
return Spreadsheet(3, 2);
}

Spreadsheet::Spreadsheet(size_t width, size_t height)
mWidth(width), mHeight(height){
mCells = new SpreadsheetCell*[mWidth];
for(size_t i = 0; i < mWidth; i++){
mCells[i] = new SpreadsheetCell[mHeight];
}
}
Spreadsheet::Spreadsheet(const Spreadsheet& src)
Spreadsheet(src.mWidth, src.mHeight){
// The ctor-initializer of this constructor delegates first to the
// non-copy constructor to allocate the proper amount of memory.
// The next step is to copy the data.
for (size_t i = 0; i < mWidth; i++) {
for (size_t j = 0; j < mHeight; j++) {
mCells[i][j] = src.mCells[i][j];
}
}
}
void Spreadsheet::verifyCoordinate(size_t x, size_t y) const{
if(x >= mWidth || y >= mHeight){
throw std::out_of_range(" ");
}
}

void Spreadsheet::setCellAt(size_t x, size_t y, const SpreadsheetCell& cell){
verifyCoordinate(x, y);
mCells[x][y] = cell;
}

SpreadsheetCell& Spreadsheet::getCellAt(size_t x, size_t y){
verifyCoordinate(x, y);
return mCells[x][y] ;
}

Spreadsheet::~Spreadsheet(){
for(size_t i = 0; i < mWidth; i++){
delete [] mCells[i];
}
delete [] mCells;
mCells = nullptr;
}

void printSpreadsheet(Spreadsheet s){

}
//实现安全处理异常的“复制和交换”惯用语法, swap()永不抛出异常, 将其标记为noexcept
void swap(Spreadsheet& first, Spreadsheet& second) noexcept{
using std::swap;
swap(first.mWidth, second.mWidth);
swap(first.mHeight, second.mHeight);
swap(first.mCells, second.mCells);
}

//Spreadsheet& Spreadsheet::operator=(const Spreadsheet& rhs){
// // check for self-assignment
// if (this == &rhs) {
// return *this;
// }
// // 创建临时副本。 Copy-and-swap idiom
// Spreadsheet temp(rhs); // Do all the work in a temporary instance
// // 创建的临时副本与当前对象交换。swap()永远不会抛出异常。
// swap(*this, temp); // Commit the work with only non-throwing operations
// //销毁临时对象, 以清理任何内存
// return *this;
//}

int main(){
// // p158
// Spreadsheet s1(4, 3);
// printSpreadsheet(s1);
// //159
// Spreadsheet s2(2, 2), s3(4, 3);
// s2 = s3;

std::vector<Spreadsheet> vec;
for(int i = 0; i < 2; ++i){
   std::cout << "Iteration " << i << std::endl;
   vec.push_back(Spreadsheet(100, 100));
   std::cout << std::endl;
}
Spreadsheet s4(2, 3);
s4 = createObject();

Spreadsheet s5(5, 6);
s5 = s4;

return 0;

}
/*
wannian07@wannian07-PC:~$ g++ -std=c++17 -o c17 c17.cpp
wannian07@wannian07-PC:~$ ./c17
Copy assignment operator
Iteration 0
Move constructor

Iteration 1
Move constructor
Move constructor

Copy assignment operator

*/

/*
#include
#include

using namespace std;

void helper(std::string&& message){
}

// lvalue reference parameter
void handleMessage(std::string& message){
cout << "handleMessage with lvalue reference: " << message << endl;
}

// rvalue reference parameter
void handleMessage(std::string&& message){
cout << "handleMessage with rvalue reference: " << message << endl;
helper(std::move(message));
}

int main()
{
std::string a = "Hello ";
std::string b = “World”;
// Handle a named variable
handleMessage(a); // Calls handleMessage(string& value)
// // Handle an expression
handleMessage(a + b); // Calls handleMessage(string&& value)
// // Handle a literal
handleMessage(“Hello World”); // Calls handleMessage(string&& value)
// // Handle a named variable and force to use rvalue reference method
handleMessage(std::move(b)); // Calls handleMessage(string&& value)
return 0;
}

wannian07@wannian07-PC:~$ g++ -std=c++17 -o c17 c17.cpp
wannian07@wannian07-PC:~$ ./c17
handleMessage with lvalue reference: Hello
handleMessage with rvalue reference: Hello World
handleMessage with rvalue reference: Hello World
handleMessage with rvalue reference: World

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值