C++でのクラスと構造体


前回C++のクラスは構造体の拡張であるという話し。
まず一般的な構造体から見ていきましょう、と。

#include <iostream>
#include <string.h>
using namespace std;
struct hoge
{
int a;
double b;
char c[128];
} foo;
int main()
{
hoge* pFoo = &foo;
foo.a = 100;
foo.b = 3.141592674;
strcpy(foo.c, "構造体のテストじゃ~。");
cout << "直接参照:\n" <<
"foo.a = " << foo.a <<
"\nfoo.b = " << foo.b <<
"\nfoo.c = " << foo.c << endl;
cout << "間接参照:\n" <<
"pFoo->a = " << pFoo->a <<
"\npFoo->b = " << pFoo->b <<
"\npFoo->c = " << pFoo->c << endl;
cout << "\n\n";
pFoo->a = 500;
pFoo->b = 1.05;
strcpy(pFoo->c, "ポインタから更新じゃじゃ~。");
cout << "直接参照:\n" <<
"foo.a = " << foo.a <<
"\nfoo.b = " << foo.b <<
"\nfoo.c = " << foo.c << endl;
cout << "間接参照:\n" <<
"pFoo->a = " << pFoo->a <<
"\npFoo->b = " << pFoo->b <<
"\npFoo->c = " << pFoo->c << endl;
return 0;
}

まぁ、これは普通に読めること前提。
一応実行結果はこれ。

直接参照:
foo.a = 100
foo.b = 3.14159
foo.c = 構造体のテストじゃ~。
間接参照:
pFoo->a = 100
pFoo->b = 3.14159
pFoo->c = 構造体のテストじゃ~。
直接参照:
foo.a = 500
foo.b = 1.05
foo.c = ポインタから更新じゃじゃ~。
間接参照:
pFoo->a = 500
pFoo->b = 1.05
pFoo->c = ポインタから更新じゃじゃ~。

で、これをそっくりクラスで書くと下記の通り。

#include <iostream>
#include <string.h>
using namespace std;
class hoge
{
public:
int a;
double b;
char c[128];
} foo;
int main()
{
hoge* pFoo = &foo;
foo.a = 100;
foo.b = 3.141592674;
strcpy(foo.c, "クラスのテストじゃ~。");
cout << "直接参照:\n" <<
"foo.a = " << foo.a <<
"\nfoo.b = " << foo.b <<
"\nfoo.c = " << foo.c << endl;
cout << "間接参照:\n" <<
"pFoo->a = " << pFoo->a <<
"\npFoo->b = " << pFoo->b <<
"\npFoo->c = " << pFoo->c << endl;
cout << "\n\n";
pFoo->a = 500;
pFoo->b = 1.05;
strcpy(pFoo->c, "ポインタから更新じゃじゃ~。");
cout << "直接参照:\n" <<
"foo.a = " << foo.a <<
"\nfoo.b = " << foo.b <<
"\nfoo.c = " << foo.c << endl;
cout << "間接参照:\n" <<
"pFoo->a = " << pFoo->a <<
"\npFoo->b = " << pFoo->b <<
"\npFoo->c = " << pFoo->c << endl;
return 0;
}

こんな風にpublic:をつけるだけ。
感がいい人はわかってると思うけど、構造体でもprivate:を付けてしまえばクラスっぽくなると言うね。
となると、構造体でもメンバ関数(メソッド)を用意することができる。

同じようなコードにすると下記なような感じになる。

#include <iostream>
#include <string.h>
using namespace std;
class CFoo
{
private:
int a;
double b;
char c[128];
public:
CFoo():a(0),b(0.0)
{
for (int i = 0; i < 128; ++i)
c[i] = '\0';
}
~CFoo() {}
int setA(int num)
{
a = num;
return 0;
}
int setB(double num)
{
b = num;
return 0;
}
int setC(char* szStr)
{
if (strlen(szStr) > 127) {
return 1;
}
strcpy(c, szStr);
return 0;
}
int getA() { return a; }
double getB() { return b; }
char* getC() { return c; }
};
struct Bar_t
{
private:
int a;
double b;
char c[128];
public:
Bar_t():a(0),b(0.0)
{
for (int i = 0; i < 128; ++i)
c[i] = '\0';
}
~Bar_t() {}
int setA(int num)
{
a = num;
return 0;
}
int setB(double num)
{
b = num;
return 0;
}
int setC(char* szStr)
{
if (strlen(szStr) > 127) {
return 1;
}
strcpy(c, szStr);
return 0;
}
int getA() { return a; }
double getB() { return b; }
char* getC() { return c; }
};
int main()
{
CFoo obj;
Bar_t obj2;
cout << "初期化時のクラス:\n" <<
"\tobj.getA() = " << obj.getA() <<
"\n\tobj.getB() = " << obj.getB() <<
"\n\tobj.getC() = " << obj.getC() << endl;
cout << "初期化時の構造体:\n" <<
"\tobj2.getA() = " << obj2.getA() <<
"\n\tobj2.getB() = " << obj2.getB() <<
"\n\tobj2.getC() = " << obj2.getC() << endl;
obj.setA(10000);
obj.setB(11.11);
obj.setC("我が輩の年齢は10万と26歳である、フハハハハ!");
obj2.setA(-1);
obj2.setB(42.195);
obj2.setC("オラ、ワクワクしてきたぞ!");
cout << "代入時のクラス:\n" <<
"\tobj.getA() = " << obj.getA() <<
"\n\tobj.getB() = " << obj.getB() <<
"\n\tobj.getC() = " << obj.getC() << endl;
cout << "代入時の構造体:\n" <<
"\tobj2.getA() = " << obj2.getA() <<
"\n\tobj2.getB() = " << obj2.getB() <<
"\n\tobj2.getC() = " << obj2.getC() << endl;
return 0;
}

何となく命名規則をそれっぽくしてみたけど、こんな感じ?
ほとんどというか、private:とpublic:を付けてしまえば両方とも一緒という結果。

そんだけ。

Post to Twitter

, , ,

  1. No comments yet.
(will not be published)