English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C++ 상속 설명 및 예제 코드

 C++상속은 단일 상속이나多重 상속이 될 수 있으며, 각 상속 연결은 public, protected, private 또는 virtual 또는 nonvirtual일 수 있습니다.-virtual. 그런 다음 각 멤버 함수 옵션은 virtual 또는 nonvirtual일 수 있습니다.-virtual 또는 pure virtual. 이 문서에서는 몇 가지 핵심 사항만 확인하겠습니다.

  public 상속, 예를 들어:

1 class 베이스
2 {...}
3 class derived:public base
4 {...}

  이렇게 작성하면 컴파일러는 derived 타입의 객체가 동시에 base 타입의 객체로 이해됩니다. 하지만 base 타입의 객체는 derived 타입의 객체가 아닙니다. 이 점이 중요합니다. 따라서 base 타입의 함수 인자는 derived 타입에 적용되지만, derived 타입의 함수 인자는 base 타입에 적용되지 않습니다. 다음은 확인 코드입니다. base 타입의 함수에 derived 타입을 전달하면 성공적으로 실행되지만, 반대로 derived 타입의 함수에 base 타입을 전달하면

#include <iostream>
#include <stdio.h>
class 베이스
{
  public:
  base()
  :baseName(""),baseData(0)
  {}
  base(std::string bn,int bd)
  :baseName(bn),baseData(bd)
  {}
  std::string getBaseName() const
  {
    return baseName;
  }
  int getBaseData()const
  {
    return baseData;
  }
  private:
    std::string baseName;
    int baseData;
};
class derived:public base
{
  public:
    derived():base(),derivedName("")
    {}
    derived(std::string bn,int bd,std::string dn)
    :base(bn,bd),derivedName(dn)
    {}
    std::string getDerivedName() const
    {
      return derivedName;
    }
  private:
    std::string derivedName;
};
void show(std::string& info,const base& b)
{
  info.append("Name is ");
  info.append(b.getBaseName());
  info.append(", baseData is ");
  char buffer[10];
  sprintf(buffer,"%d",b.getBaseData());
    info.append(buffer);
}
int main(int argc, char* argv[])
{
  base b("test",10);
  std::string s;
  show(s,b);
  std::cout<<s<<std::endl;
  derived d("btest",5,"dtest");
  std::string ss;
  show(ss,d);
  std::cout<<ss<<std::endl;
  return 0;
}

실행 결과는 다음과 같습니다:

base:baseName is test, baseData is 10
base:baseName is btest, baseData is 5

다음은 코드를 수정하여 함수 파라미터를 derived로 변경합니다.

void show2(std::string& info, const derived& d)
{
  info.append("Name is ");
  info.append(d.getBaseName());
  info.append(", baseData is ");
  char buffer[10];
  sprintf(buffer,"%d",d.getBaseData());
  info.append(buffer);
}

调用show(ss,d); 컴파일러에서 오류가 발생합니다.

1 derived_class.cpp: In function `int main(int, char**)':
2 derived_class.cpp:84: error: invalid initialization of reference of type 'const derived&' from expression of type 'base'
3 derived_class.cpp:70: error: in passing argument 2 of `void show2(std::string&, const derived&)

두 번째 점에서 다양한 상속 형태에 대해 검증을 진행합니다. 먼저 테이블을 제시합니다.

상속 방식\멤버 타입 public protected private
public public protected 상속할 수 없습니다.
protected protected protected 상속할 수 없습니다.
private private private 상속할 수 없습니다.

이곳에서 설명해 보겠습니다. 여기서는 기본 클래스의 멤버를 public, protected, private 세 가지 방식으로 상속받았을 때, 기본 클래스에서 public, protected, private 멤버가 상속 클래스에서는 테이블에 나열된 내용과 같은 타입으로 변환됩니다.

class 베이스
{
  public:
    std::string 테스트공개()
    {
      return std::string("this is public base");
    }
  protected:
    std::string testProtected()
    {
      return std::string("this is protected base");
    }
  private:
    std::string testPrivate()
    {
      return std::string("this is private base");
    }
};
class derivedPublic:public base
{
  public:
    std::string testPubPublic()
    {
      return testPublic()+= "in derived";
    }
    std::string testProPublic()
    {  
      return testProtected()+= "in derived";
    }
    std::string testPriPublic()          
    {  
      return testPrivate()+= "in derived";
    }
};
int main(int argc, char* argv[])
{
  derivedPublic dpub;
  std::cout << dpub.테스트공개() << std::endl; 
}

아래 오류가 발생하면, testPrivate()가 derived의 private 함수가 아니라 base의 private 함수라는 것을 의미합니다

derived11.cpp:16: 오류: `std::string 베이스::테스트private()'은 private입니다
derived11.cpp:36: 오류: 이 문맥 내에서

이렇게 private 타입 멤버가 상속될 수 없음을 검증합니다. (public, private, protected) 참고: private, protected는 증명을 생략합니다.

아래에서 testProtected()가 세 번째 상속 계층 클래스에 상속될 수 있지만, 세 번째 계층 클래스에서 직접 호출할 수 없다는 것을 검증하면 public 상속 후 상속된 타입이 protected이고, 기본 클래스가 Public 타입 멤버이므로 상속되고 직접 호출할 수 있습니다.

#include <iostream>
#include <string>
class 베이스
{
  public:
    std::string 테스트공개()
    {
      return std::string("this is public base");
    }
  protected:
    std::string testProtected()
    {
      return std::string("this is protected base");
    }
  private:
    std::string testPrivate()
    {
      return std::string("this is private base");
    }
};
class derivedPublic:public base
{
  public:
    std::string testPubPublic()
    {
      return testPublic()+= "in derived";
    }
    std::string testProPublic()
    {  
      return testProtected()+= "in derived";
    }
//    std::string testPriPublic()          
//    {  
//      return testPrivate()+= "in derived";
//    }
};
class deepDerived:public derivedPublic
{
  public:
    std::string deep보호된()
    {
      return testProtected() +="in deep";
    }
    std::string deep공개()
    {
      return testPublic() +="indeep";
    }
};
int main(int argc, char* argv[])
{
  derivedPublic dpub;
  std::cout << dpub.테스트보호된() << std::endl; 
  deepDerived deepdpub;
  std::cout << deepdpub.테스트공개() << std::endl;
  std::cout << deepdpub.테스트보호된() << std::endl;
  std::cout << deepdpub.deep보호된() << std::endl;
  std::cout << deepdpub.deep공개() << std::endl;
}

서버에서 오류가 발생했습니다

derived12.cpp:13: 오류: `std::string 베이스::테스트보호된()'은 보호된 멤버입니다
derived12.cpp:62: 오류: 이 문맥 내에서

이렇게 하면 public과 protected 두 가지를 검증했습니다. protected는 직접 호출할 수 없지만, 상속되면 public 멤버를 통해 호출할 수 있습니다.
아래는 이미 증명되었으므로 자세한 단계는 생략합니다. 이 부분의 검증에 관심이 있으시면 아래 코드를 참고하세요.

#include <iostream>
#include <string>
class 베이스
{
  public:
    std::string 테스트공개()
    {
      return std::string("this is public base");
    }
  protected:
    std::string testProtected()
    {
      return std::string("this is protected base");
    }
  private:
    std::string testPrivate()
    {
      return std::string("this is private base");
    }
};
class derivedPublic:public base
{
  public:
    std::string testPubPublic()
    {
      return testPublic()+= "in derived";
    }
    std::string testProPublic()
    {  
      return testProtected()+= "in derived";
    }
//    std::string testPriPublic()          //private 멤버는 상속되지 않았습니다
//    {  
//      return testPrivate()+= "in derived";
//    }
};
class deepDerived:public derivedPublic
{
  public:
    std::string test()
    {
      return testPublic() +="in 3";
    }
};
class derivedProtected:protected base
{
  public:
    std::string testPubProtected()
    {
      return testPublic()+= "in derived";
    }
    std::string testProProtected()
    {  
      return testProtected()+= "in derived";
    }
};
class deepDerived2:public derivedProtected
{
  public:
    std::string test()
    {
      return testPublic() +="in 3";
    }
};
class derivedPrivate:private base
{
  public:
    std::string testPubPirvate()
    {
      return testPublic()+= "in derived";
    }
    std::string testProPrivate()
    {  
      return testProtected()+= "in derived";
    }
};
//class deepDerived3:public derivedPrivate
//{
//  public:
//    std::string test()
//    {
//      return testPublic() +="in 3";
//    }
//};
int main(int argc, char* argv[])
{
  derivedPublic dpub;
  //derivedProtected dpro;
  //derivedPrivate dpri;
  std::cout << dpub.testPublic() << std::endl;    //
  //std::cout << dpub.testProtected() << std::endl;  //사용자가 상속되었어도 사용할 수 없습니다
  //cout << dpub.testPrivate() << std::endl;     //기본 클래스는 모두 private 함수입니다
  std::cout<<dpub.testPubPublic()<<std::endl;
  std::cout<<dpub.testProPublic()<<std::endl;
  //std::cout<<dpub.testPriPrivate()<<std::endl; //상속되지 않았습니다
  deepDerived dd;
  std::cout<<dd.test()<<std::endl;
  derivedProtected dpro;
  //std::cout<<dpro.testPublic()<<std::endl;    //protected 유형으로 변합니다
  std::cout<<dpro.testPubProtected()<<std::endl;
  std::cout<<dpro.testProProtected()<<std::endl;
  deepDerived2 dd2;
  std::cout<<dd2.test()<<std::endl;
  derivedPrivate dpri;
  std::cout<<dpri.testPubPirvate()<<std::endl;
  std::cout<<dpri.testProPrivate()<<std::endl;
//  deepDerived3 dd3;
//  std::cout<<dd3.test()<<std::endl;
}

이上是 C++ j 상속된 자료 정리, 이후 관련 자료를 계속 추가하겠습니다. 많은 지원 감사합니다!

성명서: 본 내용은 인터넷에서 가져왔으며, 저작권자는 모두 소유합니다. 내용은 인터넷 사용자가 자발적으로 기여하고 업로드한 것이며, 이 사이트는 소유권을 가지지 않으며, 인공적인 편집을 거치지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 침해 내용이 있음을 발견하시면 notice#w로 이메일을 보내 주시기 바랍니다.3codebox.com(메일을 보내는 경우 #을 @으로 변경하십시오. 신고하고 관련 증거를 제공하시면, 사실이 확인되면 해당 사이트가 즉시 침해된 내용을 삭제할 것입니다。)