2012년 5월 5일 토요일

516) public virtual List 뜻


2.6 multiple inheritance (다중 상속) 
① 의미 : 하나 이상의 class로 부터 inheritance받는 것. 
② multiple inheritance하에서의 class 계층 구조는 DAG(Directed Acyclic Graph)구조를 갖음. 
eg. class List { /*.....*/ };class Outputs : public List { /*.....*/ };
class Inputs : public List { /*.....*/ };
class Jobs
: public Outputs, public Inputs {
// .....
};
→ Outputs에서 사용하는 List와 Inputs에서 사용하는 List구조가 서로 독립적으로 존재. 그러므로 Jobs class에서 두개의 List구조가 중복하여 존재함.
④ ③과 같이 base class들을 중복하여 상속받는 것이 적당하지 않은 경우.
→ 하나의 class만을 공통으로 상속받을 수 있도록 하기 위해 virtual base class(가상 베이스 클래스)라는 개념이 있다.
eg. class List { /*.....*/ };class Outputs : public virtual List { /*.....*/ };
class Inputs : public virtual List { /*.....*/ };
class Jobs
: public Outputs, public Inputs {
// .....
};






유도된 클래스
(Derived Classes)
class Person {// .....
};
class Student : public Person {
// .....
};
void f(){
Person p1, p2;
Student s1, s2;
Person* plist; 
plist = &s1; // 리스트의 처음을 표시
s1.next = &p1; // s1과 p1을 연결
p1.next = &s2; // p1과 s2를 연결
s2.next = &p2; // s2와 p2를 연결
p2.next = 0; // p2가 끝임을 표시
}

e.g.,class Y { //..... };
class X : public Y { //..... }; 
Y y;
X x; 
① y = x; // O.K. (구겨져서 assign!!!)
② x = y; // ERROR.
eg. class X {public :
int a;
int b;
// .....
}; 
class Y : public X {
public :
int a;
// .....
}; 
void f()
{ /* 여기서 member b는 class Y에서 정의되지 않았기 때문에
scope resolution operator없이도 바로 사용할 수 */
Y y;
y.a = 1; // class Y의 member a
y.X::a = 2; // class X의 member a
y.b = 3; // class X의 member b

eg. class Shape {private :
int x, y;
protected :
int color;
public :
int pen;
// .....
}; 
class Circle : public Shape {
int rad;
public :
void draw();
// .....
}; 
void Circle :: draw() {
/* base class의 color와 pen은 사용할 수. 그러나 private member인
x, y는 사용할 수 없음 */
x++; // ERROR.
color = BLUE; // OK.
pen = 10; // OK.
// .....

void Circle::draw() {
/* derived class에서는 그 class의 object 또는 그 class에 대한 pointer나 reference등을 통해서만 base class에서 정의된 protected member를 사용할 수 → derived class라도 base class object의 protected member나 그 base class로부터 유도된 다른 class object의 protected member는 사용 할 수 없다. */ 
Shape s;
color = RED; // OK
s.color = BLACK; // ERROR
}
 
eg. class Person {char* name;
short age;
public :
Person* next; 
Person(char*, short); // Constructor
void print();
// .....
}; 
class Student : public Person {
int id;
public :
Student(char*, short, int); // Constructor
void print();
// .....
}; 
Student :: Student(char* n, short a, int sid)
: Person(n, a), id(sid)
{ ↘
// ..... (No ERROR!!! id = sid;의 의미)
}

eg. class Person {// .....
};
class Student : public Person {
// .....
}; 
void print_person(const Person* plist) {
// .....

void main(void) /* 문제점 : print_person의 인자는 Person class
{ 에 대한 pointer형이다. Person은 Student를 유
Student s; 도된 class로 가지고 있기 때문에, 실제로 p가
가리키는 object는 Person object 뿐만 아니라
print_person(&s); Student object일 수도. 그러므로 print_person
// ..... f'n에서는 object에 따른 정확한 정보를 출력
} 할 수 없다. */

class Person {// .....
public :
virtual void print(); // ①
};
class Student : public Person {
// .....
public :
void print(); // ②
}; 
void print(const Person* plist)
{
for ( ; plist; plist = plist->next)
plist->print();
}
class X {// .....
public :
virtual void f1();
virtual void f2();
virtual void f3();
};
class Y : public X {
// .....
public :
void f1();
void f2(int);
int f3(); // Compile ERROR.
};
void g()
{
X *xp = new Y; 
xp->f1(); // class Y의 f1()을 호출
xp->f2(); // class X의 f2()를 호출
}

class Shape {int x, y;
protected :
int color;
public :
int pen;
? virtual void draw() { error_handler("shape::draw"); }
virtual void draw() = 0;
}; 
class Circle : public Shape {
int rad;
public :
void draw();
}; 
class Line : public Shape {
int length;
int direction;
public :
void draw();
};
eg. class List { /*.....*/ };class Outputs : public List { /*.....*/ };
class Inputs : public List { /*.....*/ };
class Jobs
: public Outputs, public Inputs {
// .....
};
eg. class List { /*.....*/ };class Outputs : public virtual List { /*.....*/ };
class Inputs : public virtual List { /*.....*/ };
class Jobs
: public Outputs, public Inputs {
// .....
};

 
eg. class Person {// .....
public :
void* operator new(size_t);
void operator delete(void*, size_t);
// .....
};
class Student : public Person {
// .....
}; 
void f() {
Person* pp = new Student;
// .....
delete pp; // 문제점 : delete(pp, sizeof(Person))을 호출.
}

eg. class Person {// .....
public :
void* operator new(size_t);
void operator delete(void*, size_t);
virtual ~Person();
// .....
}; → 이렇게 하면 위의 문제가 delete(pp, sizeof(Student))로 해결.
→ 이때 destructor f'n은 내용이 없어도 됨.
즉, Person :: ~Person() { }

댓글 없음:

댓글 쓰기

국정원의 댓글 공작을 지탄합니다.

UPBIT is a South Korean company, and people died of suicide cause of coin investment.

 UPBIT is a South Korean company, and people died of suicide cause of coin. The company helps the people who control the market price manipu...