[c++] C ++에서 클래스와 구조체를 언제 사용해야합니까?

어떤 시나리오 에서 C ++에서 structvs 를 사용하는 것이 더 낫 class습니까?



답변

C ++에서 a class와 a의 차이점은 struct구조체에 기본 public멤버와 기본이 있고 클래스에는 기본 private멤버와 기본이 있다는 것입니다. 두 클래스와 구조체는의 혼합물을 가질 수 있습니다 public, protected그리고 private회원들은 상속을 사용할 수 있으며 멤버 함수를 가질 수 있습니다.

클래스와 같은 기능이없는 평범한 데이터 구조로 구조체를 사용하고 private데이터 및 멤버 함수가있는 집계 데이터 구조로 클래스를 사용하는 것이 좋습니다 .


답변

다른 사람들이 지적했듯이 실제로 두 가지 실제 언어 차이가 있습니다.

  • struct기본적으로 공개 액세스로, class기본적으로 개인 액세스로 설정됩니다.
  • 상속 할 때 struct기본값은 public상속이고 class기본값은 private상속입니다. (C ++의 많은 것들과 마찬가지로, 기본적으로 거꾸로되어 있습니다. public상속은 훨씬 일반적인 선택이지만 사람들 struct은 ” public“키워드 를 입력하는 것을 막기 위해 거의 선언하지 않습니다 .

그러나 실제로 진짜 차이는 사이에 class/ struct하지 않는 생성자 / 소멸자를 선언 한. “일반 데이터”POD 유형에 대한 보증이 있으며, 클래스 구성을 인수 한 후에는 더 이상 적용되지 않습니다. 이러한 차이를 명확하게 유지하기 위해 많은 사람들이 의도적으로 structPOD 유형 에만 s를 사용 하고, 메소드를 추가하려는 경우 classes를 사용 합니다. 아래 두 조각의 차이점은 의미가 없습니다.

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(우연히, 여기에 “POD 유형”이 실제로 무엇을 의미하는지에 대한 좋은 설명이있는 스레드가 있습니다 : C ++의 POD 유형은 무엇입니까? )


답변

기존 답변에는 많은 오해가 있습니다.

모두 classstruct클래스를 선언합니다.

예. 클래스를 선언하는 데 사용한 키워드에 따라 클래스 정의 내에서 액세스 수정 키워드를 다시 정렬해야 할 수도 있습니다.

그러나 구문을 넘어서서 하나를 다른 하나보다 선택해야하는 유일한 이유는 컨벤션 / 스타일 / 환경 설정입니다.

어떤 사람들은 struct멤버 함수가없는 클래스에 대한 키워드 를 고집하는 것을 좋아 합니다. 결과적인 정의는 C의 간단한 구조처럼 보입니다.

마찬가지로 일부 사람들 은 “클래스”라고 class하는 멤버 함수 및 private데이터가 포함 된 클래스에 키워드 를 사용하기를 좋아하므로 객체 지향 프로그래밍에 대한 좋아하는 책에서 예제처럼 보입니다.

현실은 이것이 당신과 당신의 팀에게 전적으로 달려 있으며, 그것은 당신의 프로그램에 문자 그대로 아무런 영향을 미치지 않을 것입니다.

다음 두 클래스는 이름을 제외한 모든면에서 완전히 동일합니다.

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

다시 선언 할 때 키워드를 전환 할 수도 있습니다.

class Foo;
struct Bar;

(이것은 부적합으로 인해 Visual Studio 빌드를 중단 하더라도이 작업을 수행 할 때 컴파일러에서 경고를 표시합니다.)

다음 표현식은 모두 true로 평가됩니다.

std::is_class<Foo>::value
std::is_class<Bar>::value

그러나 재정의 할 때 키워드를 전환 할 수는 없습니다 . 이는 (한 정의 규칙에 따라) 번역 단위에 걸쳐 클래스 정의가 중복 되어 “동일한 토큰 시퀀스로 구성 되어야 “하기 때문 입니다. 이 방법은 당신도 교환 할 수 const int member;와 함께 int const member;, 그리고 의미와는 아무 상관이 없습니다 class또는 struct.


답변

클래스 대신 구조체를 사용하는 유일한 경우는 함수 호출에서 펑터를 사용하기 직전에 선언하고 명확성을 위해 구문을 최소화하려는 경우입니다. 예 :

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 


답변

로부터 C ++ FAQ 라이트 :

구조체의 멤버와 기본 클래스는 기본적으로 public이고 클래스에서는 기본적으로 private입니다. 참고 : 기본 클래스에 의존하지 않고 기본 클래스를 명시 적으로 공개, 개인 또는 보호로 설정해야합니다.

구조체와 클래스는 기능적으로 동일합니다.

으스스하고 깨끗한 테크노 대화는 충분합니다. 감정적으로, 대부분의 개발자는 클래스와 구조체를 강력하게 구분합니다. 구조체는 단순히 캡슐화 또는 기능 방식이 거의없는 열린 비트 더미처럼 느껴집니다. 클래스는 지능적인 서비스, 강력한 캡슐화 장벽 및 잘 정의 된 인터페이스를 갖춘 살아 있고 책임감있는 사회 구성원입니다. 그것이 대부분의 사람들이 이미 가지고있는 의미이므로, 메소드가 거의없고 공개 데이터가있는 클래스가있는 경우 struct 키워드를 사용해야합니다 (이러한 것들은 잘 설계된 시스템에 존재합니다!) 예어.


답변

구조체가 나에게 도움이 된 곳은 다른 시스템에서 고정 형식 메시지 (예 : 직렬 포트)를받는 시스템이있을 때입니다. 바이트 스트림을 필드를 정의하는 구조체로 캐스트 한 다음 필드에 쉽게 액세스 할 수 있습니다.

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

분명히 이것은 C에서와 같은 일이지만 메시지를 클래스로 디코딩 해야하는 오버 헤드는 일반적으로 가치가 없다는 것을 알았습니다.


답변

내부가 C ++ 인 라이브러리를 작성하고 있지만 C 또는 C ++ 코드로 API를 호출 할 수있는 경우 C ++에서 “struct”를 사용할 수 있습니다. C와 C ++ 코드 모두에 노출되는 구조체와 전역 API 함수를 포함하는 단일 헤더를 만들면됩니다.

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif

// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;

// Put your C API functions here
void bar(foo *fun);

#ifdef __cpp
}
#endif

그런 다음 C ++ 코드를 사용하여 C ++ 파일에 함수 bar ()를 작성하고 C에서 호출 가능하게 만들고 두 세계는 선언 된 구조체를 통해 데이터를 공유 할 수 있습니다. 물론 C와 C ++를 혼합 할 때 다른 경고가 있지만 이것은 간단한 예입니다.