1. ホーム
  2. c++

[解決済み] C++ スタッククラスのコピーコンストラクタを作成する

2022-02-09 01:29:25

質問

スタックに値をプッシュしたりポップしたりするメソッドを含むスタッククラスを定義しました。

テスターファイル(下図)を実行すると、&が発生し、プログラムがクラッシュしてしまいます。これは、2つのポインタがメモリ内の同じ場所を指しているため、エラーを発生させる関数fが原因であることが分かっています。この関数が呼び出されたときに f(s) という行をコメントアウトすると、pop & push 関数は正しく動作し、出力も正しくなります。

このエラーを修正するために、私は ; このクラスのコピーコンストラクタを作成し、上記の問題を解決するように求められました。

あまり慣れていないので、どのようにすればよいか、ご教示いただければ幸いです。ありがとうございます。

メインテストファイル

#include "Stack.h"
#include <iostream>
#include <string>
using namespace std;

void f(Stack &a) {
    Stack b = a;
}


int main() {

    Stack s(2); //declare a stack object s which can store 2 ints
    s.push(4); //add int 4 into stack s

    //s = [4]
    s.push(13); //add int 13 into stack s
    //s = [4,13]

    f(s); //calls the function f which takes in parameter Stack a , and sets Stack b = to it.
    //error here - as 2 pointers point to the same location in memory !
    cout << s.pop() << endl; //print out top element(most recently pushed) element.
    //so should output 13
    return 0;
}

ヘッダーファイルのコード

#ifndef STACK_H
#define STACK_H

class Stack {
public:
    //constructor
    Stack(int size);

    //destructor
    ~Stack();

    //public members (data & functions)
    void push(int i);
    int pop();

private:
    //private members (data & functions)
    int stck_size;
    int* stck;
    int top;
};

#endif

Stack.cppのコード

#include "Stack.h"
#include <iostream>
#include <string>
using namespace std;

Stack::Stack(int size){
    stck_size = size;
    stck = new int[stck_size];
    top = 0;
}
Stack::~Stack() {
    delete[] stck;
}
void Stack::push(int i) {
    if (top == stck_size) {
        cout << "Stack overflow." << endl;
        return;
    }
    stck[top++] = i;
}

int Stack::pop() {
    if (top == 0) {
        cout << "Stack underflow." << endl;
        return 0;
    }
    top--; //decrement top so it points to the last element istead of the empty space at the top.
    return stck[top];
}

解決方法は?

このコピーコンストラクタは、かなり手っ取り早いです。

Stack::Stack(const Stack & src): 
    stck_size(src.stack_size),
    stck(new int[stck_size]),
    top(src.top) //Member Initializer List
{
    // copy source's stack into this one. Could also use std::copy.
    // avoid stuff like memcpy. It works here, but not with anything more 
    // complicated. memcpy is a habit it's just best not to get into
    for (int index = 0; index < top; index++)
    {
        stck[index] = src.stck[index];
    }
}

コピーコンストラクタができたので、まだ失敗の可能性があります。 ルール・オブ・スリーは満たされていない。 必要なのは operator= . そしてこれは簡単で、コピー構文と コピーとスワップのイディオムで簡単にできます。

基本形です。

TYPE& TYPE::operator=(TYPE rhs) //the object to be copied is passed by value
                                // the copy constructor makes the copy for us.
{
  swap(rhs); // need to implement a swap method. You probably need one 
             //for sorting anyway, so no loss.
  return *this; // return reference to new object
}