インライン関数

複数の関数間での呼び出しは通常、システムスタックに高位アドレスから低位アドレスに向かって、積まれるそうだ。(例のpush-pop)。この作業に時間がかかり、場合によってはオーバーヘッドの一因になるそうな。(オーバーヘッド?)
上記の場合を避けるために、簡単な処理であればマクロを使ってインライン関数化するのがいいそうだ。
では、どうするか。
組み込み型データのコピーはビットコピーするだけだから、単純な操作であろう。しかし、オブジェクトのコピーはそうはいかないようだ。
Cでは、こんな感じ。
int summation(int a,int b){
int sum=a+b;
return sum;
}
こいつを
#define summation(int a,int b) {(a)+(b)} としてやる。


関数定義の前にインライン関数を定義する方法。
#include<iostream>
using namespace std;
//インライン関数を定義
inline int add(int i,int j){return i+j;}

int main()
{
int result;
result=add(5,3);//add関数を呼び出す
cout<<result<<endl;
return 0;
}

すごいのはインラインが自動的に行われることだ。短かく定義されたメンバ関数をコンパイラによって、自動的にインライン化される。
#include<iostream>
using namespace std;
class tester{
int i,j;
public:
sample(int a,int b);
//クラス定義内で定義されたインライン関数
int add(){return i+j;}
};

sample::sample(int a,int b)
{
i=a;j=b;
}

と簡単に述べてみたが、インライン関数の本当の意味は現時点の筆者のレベルからすると理解しがたい点が多いため、更なる勉強が必要だ。

コピーコンストラクタ

/****コピーコンストラクタを生成、オブジェクトを関数に渡す*****/
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;

class stringtype{
char *p;
public:
stringtype(char *s);
stringtype(const stringtype &ob);
~stringtype(){
delete []p;}
char *get(){
return p;
}
};
stringtype::stringtype(char *s)
{
int l;
l=strlen(s)+1;//strlen()method

p=new char[l];
if(!p){
cout<<"unable get a memory field"<<endl;
exit(1);
}
strcpy(p,s);//strcpy()method
}
stringtype::stringtype(const stringtype &ob)
{
int l;
l=strlen(ob.p)+1;

p=new char[l];
if(!p){
cout<<"unable get a memory field"<<endl;
exit(1);
}
strcpy(p,ob.p);//文字列をコピーオブジェクトにコピー
}

void show(stringtype x)
{
char *s;
s=x.get();
cout<<s<<endl;
}
int main()
{
stringtype e("see you"),d("good luck");

show(e),show(d);
return 0;
}

//出力結果

see you
good luck

コピーコンストラクタ

/*****プログラム概要******/
/**動的に配列を割り当て、配列オブジェクトを生成しかつ他の配列オブジェクトを初期化するとき、コピーコンストラクタでメモリ割り当てをする***/
#include<iostream>
#include<cstdlib>
using namespace std;
class array{
int *p;
int size;
public:
//通常のコンストラクタ
array(int s){
p=new int[s];
if(!p)
exit(1);
size=s;
cout<<"通常のコンストラクタを使う"<<endl;
}
~array(){
delete []p;}
//copy constructor
array(const array &a);

void set(int i,int j){
if(i>=0 && i<size)
p[i]=j;
}
int get(int i){
return p[i];
}
};
/*このコンストラクタでコピー用にメモリを確保してそのメモリアドレスをpに当てる。pが元のオブジェクトと同等のメモリを参照することはない**/
array::array(const array &a){
int i;
size=a.size;
p=new int[a.size];
if(!p)
exit(1);
for(i=0;i<a.size;i++)
p[i]=a.p[i];
cout<<"コピーコンストラクタを使う"<<endl;
}

int main()
{
array num(10);  //通常のコンストラクタを呼び出す
int i;

for(i=0;i<10;i++)
num.set(i,i);

for(i=9;i>=0;i--)
cout<<num.get(i);
puts("");

array x=num; //他の配列を生成して、numで初期化

for(i=0;i<10;i++)
cout<<x.get(i);
puts("");

return 0;
}


コマンドプロンプトへの出力結果
通常のコンストラクタを使う
9876543210
コピーコンストラクタを使う
0123456789

文字の配列

Cの文字列は、難しいと思う。
文字列型がないので、文字型charを使って、配列にしてやらなければならないようだ。言わば、文字型配列だ。
加えて、2次元配列などはなく、厳密には配列の配列であり、char str[3][ ]は char *str[ ]は同義だ。
したがって、以下は同じ動きをする。

#include<stdio.h>

int main(void)
{
    char str[3][ ]={{"asahikawa"},{"sapporo"},{"hakodate"}};
    int i;
    char *strp[ ]={{"asahikawa"},{"sapporo"},{"hakodate"}};
   
    for(i=0;i<3;i++)
        printf("%s\n",str[i]);
    puts("");   
   
    for(i=0;i<3;i++)
        printf("%s\n",strp[i]);           
   
    return 0;
}

Nikkei225

28000-28550 up in the early session, down lately.