#include <iostream>
using namespace std;
template <class T>
void out(T t) { cout << t << endl; }
void out(char *str) { cout << str << endl; }
template <class T>
void out(char *str, T t) { cout << str << ' ' << t << endl; }
class VirtualClass {
public:
void virtual_func() { out("vir"); }
};
class PublicClass : public virtual VirtualClass {
private:
void pub_private_func() {}
protected:
void pub_protected_func() {}
public:
void virtual_func() { out("pub"); }
void pub_public_func() {}
void override_fail_func() { out("pub"); }
virtual void override_success_func() { out("pub"); }
virtual void need_override_func() = 0;
};
class PrivateClass : public virtual VirtualClass {
private:
void prv_private_func();
protected:
void prv_protected_func();
public:
void virtual_func() { out("prv"); }
void prv_public_func();
PrivateClass(int x) {}
};
class ProtectedClass {
private:
void prt_private_func();
protected:
void prt_protected_func();
public:
void prt_public_func();
};
class MyClass : public PublicClass, private PrivateClass,
protected ProtectedClass, public virtual VirtualClass
{
friend class FriendClass;
friend void friend_func(MyClass& mc);
private:
static const int static_const_value;
static int static_private_value;
const int const_value;
int private_value;
void private_func();
void func_access_prv() {
// pub_private_func(); //NG
pub_protected_func(); //OK
pub_public_func(); //OK
// prv_private_func(); //NG
prv_protected_func(); //OK?
prv_public_func(); //OK?
// prt_private_func(); //NG
prt_protected_func(); //OK?
prt_public_func(); //OK?
}
void fa_prv() { func_access_prv(); }
protected:
int protected_value;
void protected_func();
void func_access_prt() {
// pub_private_func(); //NG
pub_protected_func(); //OK
pub_public_func(); //OK
// prv_private_func(); //NG
prv_protected_func(); //OK?
prv_public_func(); //OK?
// prt_private_func(); //NG
prt_protected_func(); //OK?
prt_public_func(); //OK?
}
void fa_prt() { func_access_prt(); }
public:
MyClass(); //コンストラクタ
MyClass(int x); //コンストラクタ(オーバーロード)
MyClass(const MyClass& mc) : PrivateClass(5), const_value(mc.const_value) {
private_value = MyClass::static_private_value++;
}
~MyClass(); //デストラクタ
static void static_public_func();
int public_value;
void public_func();
void virtual_func() { out("my"); }
void override_fail_func() { out("my"); }
void override_success_func() { out("my"); }
void need_override_func() {}
void const_ng_func() {}
void const_ok_func() const {}
inline int getPrivateValue() const {
return private_value;
}
operator int() const {
return const_value;
}
MyClass operator + (const MyClass& mc) {
out("op+ l pv", private_value);
out("op+ l cv", const_value);
out("op+ r pv", mc.private_value);
out("op+ r cv", mc.const_value);
MyClass mc2(const_value + mc.const_value);
out("op+ pv", mc2.private_value);
out("op+ cv", mc2.const_value);
return mc2;
}
void func_access_pub() {
// func_access_prv(); //NG
// func_access_prt(); //NG
// pub_private_func(); //NG
pub_protected_func(); //OK
pub_public_func(); //OK
// prv_private_func(); //NG
// prv_protected_func(); //NG
// prv_public_func(); //NG
// prt_private_func(); //NG
// prt_protected_func(); //NG
// prt_public_func(); //NG
}
};
const int MyClass::static_const_value = 123;
int MyClass::static_private_value = 1;
void MyClass::static_public_func() { out("spf"); }
void MyClass::private_func() {}
void MyClass::protected_func() {}
void MyClass::public_func() {}
MyClass::MyClass() : PrivateClass(1), const_value(1) {
private_value = MyClass::static_private_value++;
}
MyClass::MyClass(int x) : PrivateClass(x * 2), const_value(x) {
private_value = MyClass::static_private_value++;
}
MyClass::~MyClass() { out("des:", private_value); }
void friend_func(MyClass& mc) {
mc.private_value = 777;
}
int main() {
MyClass mc;
MyClass mc1(123);
const MyClass mc2(999);
MyClass mc3 = 9876;
MyClass *mc4 = new MyClass; //動的割り当て
MyClass *mc5 = new MyClass(789); //動的割り当て
PublicClass *pub = &mc; //OK
// PrivateClass *prv = &mc; //NG
// ProtectedClass *prt = &mc; //NG
VirtualClass *vir = &mc; //OK
out("Public Value");
out(mc.public_value = 333);
out("Virtual Class.");
pub->virtual_func(); //pub
vir->virtual_func(); //vir
mc.virtual_func(); //my
mc.VirtualClass::virtual_func(); //vir
mc.PublicClass::virtual_func(); //pub
// mc.PrivateClass::virtual_func(); //NG
// mc.ProtectedClass::virtual_func(); //NG
out("Static Function");
MyClass::static_public_func();
out("Friend Function");
friend_func(mc);
out("Inline Function");
out(mc.getPrivateValue());
out("Override Fail Function");
pub->override_fail_func(); //pub
mc.override_fail_func(); //my
mc.PublicClass::override_fail_func(); //pub
out("Override success Function");
pub->override_success_func(); //my
mc.override_success_func(); //my
mc.PublicClass::override_success_func(); //pub
out("Base Class");
// mc.pub_private_func(); //NG
// mc.pub_protected_func(); //NG
mc.pub_public_func(); //OK
// mc.prv_private_func(); //NG
// mc.prv_protected_func(); //NG
// mc.prv_public_func(); //NG
// mc.prt_private_func(); //NG
// mc.prt_protected_func(); //NG
// mc.prt_public_func(); //NG
out("Function Access");
mc.func_access_pub();
out("Override Operator");
out("mc3 pv", mc3.getPrivateValue());
out("mc3 cv", (int)mc3);
MyClass mc6;
out("mc6 pv", mc6.getPrivateValue());
out("mc6 cv", (int)mc6);
out(mc6 + mc3 + *mc5);
out("Const Class");
// mc2.const_ng_func(); //NG
mc2.const_ok_func(); //OK
out("delete.");
delete mc4;
delete mc5;
out("deleted.");
return 0;
}