C++メモ書き 参照仮引数

参考書の練習問題にて、プログラムの間違いを指摘して参照型仮引数を使って修正を行えとのこと(元のとは一部変えてあります)

#include<iostream>
#include<cstdlib>
#include<cstring>

using namespace std;

class strtype{
  char *p;
  int l;
public:
  strtype(char *s);
  ~strtype(){free(p);};
  char *get(){return p;};
};

strtype::strtype(char *s){
  int i;
  
  l=strlen(s)+1;
  p=(char *)malloc(l*sizeof(char));

  if(!p){
    cout << "メモリ割り当てエラー\n";
    exit(1);
  }
  strcpy(p,s);
}

void show(strtype x){
  
  cout<<x.get()<<"\n";
}

int main(){
  strtype a("Hello"),b("World");

  show(a);
  show(b);

  return 0;
}

オブジェクトをshow()に値渡しされ、オブジェクトのコピーが作成
終了するとコピーが破棄されたのちデストラクタが呼び出されpが解放されるが、pの指すアドレスはまだ必要とされている

オブジェクトのコピーが作成されないよう、これを参照仮引数を使って修正すると以下のように

#include<iostream>
#include<cstdlib>
#include<cstring>

using namespace std;

class strtype{
  char *p;
  int l;
public:
  strtype(char *s);
  ~strtype(){free(p);};
  char *get(){return p;};
};

strtype::strtype(char *s){
  int i;
  
  l=strlen(s)+1;
  p=(char *)malloc(l*sizeof(char));

  if(!p){
    cout << "メモリ割り当てエラー\n";
    exit(1);
  }
  strcpy(p,s);
}

void show(strtype &x){
  
  cout<<x.get()<<"\n";
}

int main(){
  strtype a("Hello"),b("World");

  show(a);
  show(b);

  return 0;
}

ここで注意したいのはshow()関数の仮引数"&x"はポインタではないこと。なのでget()メソッドを呼び出すときはアロー演算子ではなくドットを使っている。このときxを参照変数と言う




以下、最初に「参照仮引数を使って」をガン無視して修正したコード

#include<iostream>
#include<cstdlib>
#include<cstring>

using namespace std;

class strtype{
  char *p;
  int l;
public:
  strtype(char *s);
  ~strtype(){free(p);};
  char *get(){return p;};
};

strtype::strtype(char *s){
  int i;
  
  l=strlen(s)+1;
  p=(char *)malloc(l*sizeof(char));

  if(!p){
    cout << "メモリ割り当てエラー\n";
    exit(1);
  }
  strcpy(p,s);
}

void show(strtype *x){
  
  cout<<x->get()<<"\n";
}

int main(){
  strtype *a=new strtype("Hello"),*b=new strtype("World");

  show(a);
  show(b);

  delete a;
  delete b;
  
  return 0;
}

問題文はちゃんと読もう(戒め)