구조체에 생성자를 추가해야합니까?


14

우리는 종종 멤버 메소드를 가진 완전한 모듈 일 수있는 클래스와 달리 데이터 구조를 정의하기 위해 c ++ 구조체를 사용합니다. 이제 깊게, 우리는 둘 다 동일하다는 것을 알고 있습니다.

데이터 만 엔티티로 구조체를 자주 사용 / 처리한다는 사실 때문에 기본 생성자를 추가하지 않아도된다는 충동이 생깁니다. 그러나 생성자는 항상 훌륭하며 일을 더 단순하게 만들고 오류를 제거하는 데 도움이됩니다.

내 데이터 구조에 기본 생성자를 추가하면 눈살을 찌푸리게됩니까?

기본 생성자를 구현 하면 다른 기준이 충족되면 struct Non-POD (일반 이전 데이터 유형)도 만들 수 있습니까?

사물을 원근법으로 나타내려면 간단한 예를 고려하지만 실제로는 구조가 훨씬 더 큽니다.

struct method
{
    char    name[32];
    float   temperature;
    int     duration;
};

메소드를 만들 때마다 값을 설정하지 않은 경우 걱정할 필요가 없습니다. temperature이제 임의의 높은 값을 가지며 시스템을 손상시키는 시스템에 방법 을 설정 하고 적용하는 것을 잊었다 고 상상해보십시오 . 또는 설정을 잊어 버렸고 duration이제는 방법이 알려지지 않은 높은 기간 동안 적용됩니다.

객체를 보장하는 생성자를 구현하는 대신 매번 객체를 초기화해야하는 이유는 무엇입니까?


특정 값만 허용하도록 강제해야하는 경우 일반 데이터 유형이 없습니다. 구조체를 초기화하는 편리한 방법을 원한다면 평범한 오래된 함수가 그렇게 할 것입니다.
Doval

이러한 생성자가 수행하는 작업에 따라 다릅니다. 기본 방식으로 필드 값을 설정하는 경우 간단한 구조체에서 생성자를 갖는 것이 완전히 합리적이라고 생각합니다.
로봇

@Doval 그것은 질문이 아닙니다. 나는 게시물을 업데이트했습니다. Steven : 그렇습니다. 생성자는 기본값 만 지정합니다.
zadane

@StevenBurnap : 생성자가 기본 방식으로 필드 값을 설정하는 것 이상의 작업을 수행 하는 것이 적합합니다. 구조체에서도.
Jan Hudec

2
내 말은 생성자에서 복잡한 논리를 찾기 시작하면 클래스로 만들어야 할 가능성이 있다는 것입니다. (IMHO) 그러나 사이의 유일한 실제 차이로 정말 스타일 질문 structclass하나 개인 기본값과 대중에게 다른 것입니다.
로봇

답변:


13

때로는 구조체에 생성자를 추가하는 것이 적절하고 때로는 그렇지 않습니다.

구조체에 생성자 (생성자)를 추가하면 집계 초기화 프로그램을 사용할 수 없습니다. 따라서 기본 생성자를 추가하는 경우 값을 초기화하는 기본이 아닌 생성자를 정의해야합니다. 그러나 항상 모든 멤버를 초기화하려면 적절합니다.

생성자 (생성자 모두)를 추가하면 POD가 아닌 것이되지만 C ++ 11에서는 이전에 POD에 적용되었던 대부분의 규칙이 표준 레이아웃 객체에만 적용되도록 변경되었으며 생성자를 추가해도 문제가 해결되지 않습니다. 따라서 집계 초기화 프로그램은 기본적으로 유일하게 손실됩니다. 그러나 종종 큰 손실입니다.


8

11 ++ C 당신은 할 수있다

struct method
{
    char    name[32] {};
    float   temperature = 42.141521;
    int     duration = -6;
};

그리고 무언가를 초기화하는 것을 잊을 때마다 기본 초기화가 수행됩니다.


-1

빠른 답변 :

그것은 당신이 달성하고자하는 것에 달려 있습니다.

길고 확장 된 지루한 답변 :

당신은 못을 쳤다.

나는 보통 "C ++"가 "Struct (s)"가 메소드를 선언 할 수 있다는 것을 싫어한다. 바람직하게는 필자는 필요한 메소드에 대해 명시 적 "클래스 (es)"를 사용하고 필드에만 POD "구조 (s)"를 사용합니다.

그러나 나는 다음과 같은 기본적인 간단한 작업에 동의합니다.

  • 초기 값 할당 ( "생성자")
  • 구조의 사본 만들기 ( "복사 생성자)
  • 기존 구조에 값 할당 ( "과부하 할당 연산자")

이러한 환경에서는 구조를위한 방법이 필요하며 그 의미가 있습니다.

암시

또 다른 가능한 해결책은 POD 구조를 사용하는 것이지만 개념적으로 클래스와 객체로 취급하는 것입니다.

이러한 선언을 네임 스페이스로 감싸고 가장 중요한 작업을 위해 전역 함수를 추가하십시오.

코드 선언은 다음과 유사 할 수 있습니다.

namespace Customers
{
  struct CustomerStruct
  {
    char[255] FirstName;
    char[255] LastName;
    int Age;
    bool IsAlive;
    bool IsMarried;
  }; // struct

  CustomerStruct* CreateCustomer
  (
    char* NewFirstName;
    char* NewLastName;
    int NewAge;
    bool NewIsAlive;
    bool NewIsMarried;
  )
  {
    CustomerStruct* NewCustomer = new CustomerStruct();
      NewCustomer->FirstName = NewFirstName;
      NewCustomer->LastName = NewLastName;
      NewCustomer->Age = NewAge;
      NewCustomer->IsAlive = NewIsAlive;
      NewCustomer->IsMarried = NewIsMarried;
    return NewCustomer;
  } // CustomerStruct* CreateCustomer (...)

} // namespace

솔루션을 적용하는 코드는 다음과 같습니다.

#include <Customers>

using Customers;

int main (...)
{
   int ErrorCode = 0;

   CustomerClass* ThisCustomer =
     Customers::CreateCustomer
      ("John", "Doe", 23, true, true);

   // do something with "ThisCustomer"

   delete ThisCustomer;

   return ErrorCode;
} // int main(...)

이 대체 방법은 데이터의 메모리 할당량이 많거나 다른 저수준 공유 라이브러리와 상호 작용할 때 더 좋습니다.

이 접근 방식은 일부 변경 사항이 있으며 게임 개발에 적용됩니다.

특별한

개인적으로, 나는 "C ++"에 대한 구문 확장, 또는이 문제를 해결하는 새로운 "C ++"기반 PL을 고려합니다.

// "Plain Old Data" Structure
// No Methods, No "Functors", allowed
strict struct CustomerStruct
{
  char[255] FirstName;
  char[255] LastName;
  int Age;
  bool IsAlive;
  bool IsMarried;
}; // strict struct

// Object Oriented "Plain Old Data" Structure
// Yes, Methods and "Functors" allowed
relaxed struct CustomerStruct
{
  char[255] FirstName;
  char[255] LastName;
  int Age;
  bool IsAlive;
  bool IsMarried;

  public void Foo();
  public void Bar();

  public (void*) (SomeFunctor) ();
}; // relaxed struct

// Class and Object Oriented
class CustomerClass
{
  public char[255] FirstName;
  public char[255] LastName;
  public int Age;
  public bool IsAlive;
  public bool IsMarried;

  public void Foo();
  public void Bar();
}; // class

건배.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.