programing tip

매개 변수가없는 생성자를 만들 때 기본 매개 변수없는 생성자가 사라지는 이유

itbloger 2020. 6. 3. 21:33
반응형

매개 변수가없는 생성자를 만들 때 기본 매개 변수없는 생성자가 사라지는 이유


C #, C ++ 및 Java에서 매개 변수를 사용하는 생성자를 작성하면 기본 매개 변수없는 구성 요소가 사라집니다. 나는 항상이 사실을 받아 들였지만 이제는 왜 그런지 궁금해하기 시작했습니다.

이 행동의 이유는 무엇입니까? "자신의 생성자를 만든 경우이 암시 적 생성자를 원하지 않을 "이라고 말하는 것이 "안전 측정 / 추측" 일 뿐입니 까? 또는 생성자를 직접 만든 후에는 컴파일러에서 컴파일러를 추가 할 수없는 기술적 이유가 있습니까?


직접 추가 한 경우 컴파일러에서 생성자를 추가 할 수있는 이유는 없습니다. 컴파일러는 원하는대로 수행 할 수 있습니다! 그러나 가장 적합한 것이 무엇인지 살펴 봐야합니다.

  • 비 정적 클래스에 대한 생성자를 정의 하지 않은 경우 해당 클래스를 인스턴스화 할 수 있기를 원할 것입니다. 이를 허용하기 위해 컴파일러 매개 변수가없는 생성자를 추가 해야합니다 . 즉, 코드를 작성하기 위해 빈 생성자를 내 코드에 포함시킬 필요가 없습니다.
  • 내 자신의 생성자, 특히 매개 변수가있는 생성자를 정의했다면 클래스를 만들 때 실행 해야하는 내 자신의 논리가있을 가능성이 큽니다. 컴파일러 가이 경우 빈 매개 변수가없는 생성자를 만들면 누군가 내가 작성한 논리 건너 뛸 수 있으므로 여러 가지 방법으로 코드가 손상 될 수 있습니다. 이 경우 기본 빈 생성자를 원하면 명시 적으로 말해야합니다.

따라서 각 경우에 현재 컴파일러의 동작 이 코드의 의도보존하는 데 가장 적합하다는 것을 알 수 있습니다 .


언어 이런 식으로 설계되어야 하는 기술적 이유는 없습니다 .

내가 볼 수있는 다소 현실적인 옵션이 있습니다.

  1. 기본 생성자가 전혀 없습니다
  2. 현재 시나리오
  3. 기본적으로 항상 기본 생성자를 제공하지만 명시 적으로 억제되도록 허용
  4. 억제 하지 않고 항상 기본 생성자 제공

옵션 1은 더 I 코드가 덜 자주는 점에서 다소 매력적이다 정말 매개 변수없는 생성자를 원한다. 언젠가 나는 기본 생성자를 사용하여 실제로 얼마나 자주 끝나는 지 계산해야합니다 ...

옵션 2 괜찮습니다.

옵션 3은 나머지 언어에 대해 Java와 C #의 흐름에 반합니다. Java에서 기본적으로 사적인 것들을 명시 적으로 만드는 것을 제외하고는 명시 적으로 "제거"하는 것은 없습니다.

옵션 4 끔찍 - 당신은 절대적으로 특정 매개 변수와 건설을 강제 할 수 있어야합니다. 무엇을 new FileStream()의미할까요?

그러니까 기본적으로, 경우에 당신은 기본 생성자를 제공하는 것이 전혀 의미가 있다는 전제를 받아, 나는 그것이 바로 당신이 당신의 자신의 생성자를 제공하기로 억제하는 많은 이해 믿습니다.


편집하다. 사실, 첫 번째 답변에서 내가 말하는 것은 유효하지만 이것이 진정한 이유입니다. :

처음에는 C가있었습니다. C는 객체 지향적이지 않습니다 (OO 접근 방식을 취할 수는 있지만 도움이되지는 않습니다).

그런 다음 C With Classes가 있었고 나중에 C ++로 이름이 바뀌 었습니다. C ++는 객체 지향적이므로 캡슐화를 권장하고 구성시 및 메소드 시작 및 종료시 객체가 유효한 상태에있게합니다.

이것과 관련된 자연스러운 일은 클래스가 항상 유효한 상태에서 시작되도록 생성자가 있어야한다는 것입니다. 생성자가 이것을 보장하기 위해 아무것도 할 필요가 없다면 빈 생성자는이 사실을 문서화합니다 .

그러나 C ++의 목표는 가능한 한 모든 유효한 C 프로그램도 유효한 C ++ 프로그램 (더 이상 목표가 유효하지 않으며 C의 C ++ 로의 진화는 더 이상 보유하지 않는다는 점)까지 C와 호환되어야했습니다. ).

이 중 하나 개 효과는 간 기능의 중복이었다 structclass. 전자는 C 방식으로 작업을 수행하고 (기본적으로 모든 것을 공개) 후자는 좋은 OO 방식으로 작업을 수행합니다 (기본적으로 개인은 개발자가 원하는 것을 공개적으로 공개합니다).

또 다른 방법은 struct생성자가 없기 때문에 생성자를 가질 수없는 C의 경우 C ++에서 유효하기 때문에 C ++ 방식을 보는 의미가 있어야한다는 것입니다. 따라서 생성자가없는 것은 변형을 적극적으로 보장하는 OO 관행에 위배되지만 C ++은 빈 본문이있는 것처럼 작동하는 기본 매개 변수가없는 생성자가 있음을 의미했습니다.

모든 C structs는 이제 유효한 C ++ structs이었습니다. classes이것은 마치 매개 변수가없는 단일 생성자가있는 것처럼 외부에서 모든 것을 처리하는 C ++ 동일합니다 ( 구성원 및 상속-공용).

그러나 생성자를 classor 에 넣으면 structC 방식이 아닌 C ++ / OO 방식으로 작업을 수행했으며 기본 생성자가 필요하지 않았습니다.

간결한 역할을했기 때문에 호환성이 불가능한 경우에도 사람들은 계속 사용했습니다 (C가 아닌 다른 C ++ 기능을 사용했습니다).

따라서 Java가 여러 가지 방법으로 C ++을 기반으로하고 나중에 C # (여러 가지 방법으로 C ++ 및 Java를 기반으로)을 도입했을 때 이미 코더가 익숙한 것처럼이 접근법을 유지했습니다.

Stroustrup은 C ++ 프로그래밍 언어로 이에 대해 기술하고 있으며 C ++ 의 디자인과 진화 에서 언어의“왜”에 더 초점을 맞추고 있습니다 .

=== 원래 답변 ===

이것이 일어나지 않았다고 가정 해 봅시다.

클래스가없는 상태를 의미있는 상태로 만들 수 없기 때문에 매개 변수가없는 생성자를 원하지 않는다고 가정 해 봅시다. 실제로 이것은 structC #에서 발생할 수있는 일입니다 (그러나 C #에서 0을 null struct의미있게 사용할 수 없다면 공개적으로 볼 수없는 최적화를 사용하는 것이 가장 좋습니다. struct) 를 사용하여 디자인 결함이 있습니다.

클래스가 불변을 보호 할 수있게하려면 특별한 removeDefaultConstructor키워드 가 필요 합니다. 최소한 호출 코드가 기본값을 호출하지 않도록 개인 매개 변수가없는 생성자를 만들어야합니다.

언어를 좀 더 복잡하게 만듭니다. 하지 않는 것이 좋습니다.

대체로 생성자를 추가하는 것으로 생각하지 않는 것이 가장 좋습니다. 아무것도하지 않는 매개 변수가없는 생성자를 추가하기 위해 생성자가없는 구문 설탕으로 생각하는 것이 좋습니다.


객체 생성을 제어하기 위해 직접 작업을 수행하지 않으면 기본 매개 변수가없는 생성자가 추가됩니다. 제어 할 단일 생성자를 만든 후에는 컴파일러가 "백 오프"하여 모든 권한을 갖습니다.

If it wouldn't be this way, you would need some explicit way of disabling the default constructor if you only want objects to be constructable through a constructor with parameters.


It's a convenience function of the compiler. If you define a Constructor with parameters but don't define a parameterless constructor, the possibility that you don't want to allow a parameterless constructor is much higher.

This is the case for many objects that just don't make sense to initialize with an empty constructor.

Otherwise you'd have to declare a private parameterless constructor for each class that you want to restrict.

In my opinion it's not good style to allow a parameterless constructor for a class that needs parameters to function.


I think the question should be the other way around: Why don't you need to declare a default constructor if you haven't defined any other constructors?

A constructor is mandatory for non-static classes.
So i think if you haven't defined any constructors, the generated default constructor is just a convenient feature of the C# compiler, also your class wouldn't be valid without a constructor. So nothing wrong with implicitly generating a constructor that does nothing. It certainly looks cleaner than having empty constructors all around.

If you have already defined a constructor, your class is valid, so why should the compiler assume you want a default constructor? What if you don't want one? Implement an attribute to tell the compiler to not generate that default constructor? I don't think that would be a good idea.


The default constructor can be constructed only when the class doesn't have a constructor. Compilers are written in such a way as to provide this only as a backup mechanism.

If you have a parameterized constructor, you may not want an object to be created using the default constructor. Had the compiler provided a default constructor, you would have had to write a no-arg constructor and make it private in order to prevent objects being created using no arguments.

Also, there would be higher chances of you forgetting disabling, or 'privatising' the default constructor, and thereby causing a potential functional error hard to catch.

And now you have to explicitly define a no-arg constructor if you'd like an object to be created either the default way or by passing parameters. This is strongly checked, and the compiler complains otherwise, thereby ensuring no loophole here.


Premise

This behaviour can be seen as a natural extension of the decision for classes to have a default public parameterless constructor. Based on the question that's been asked we take this decision as a premise and assume that we are not questioning it in this instance.

Ways to Remove Default Constructor

It follows that there must be a way to remove the default public parameterless constructor. This removal could be accomplished in the following ways:

  1. Declare a non-public parameterless constructor
  2. Automatically remove the parameterless constructor when a constructor with parameters is declared
  3. Some keyword / attribute to indicate to the compiler to remove the parameterless constructor (awkward enough that it is easy to rule out)

Selecting the Best Solution

Now we ask ourselves: If there is no parameterless constructor, what must it be replaced by? and Under what types of scenarios would we want to remove the default public parameterless constructor?

Things start to fall in place. Firstly, it must either be replaced with a constructor with parameters, or with a non-public constructor. Secondly, the scenarios under which you do not want a parameterless constructor are:

  1. We do not want the class to be instantiated at all, or we want to control the visibility of the constructor: declare a non-public constructor
  2. We want to force parameters to be provided on construction: declare a constructor with parameters

Conclusion

There we have it -- exactly the two ways that C#, C++ and Java allow the removal of the default public parameterless constructor.


I think this is handled by the compiler. If you open the .net assembly in ILDASM you will see the default constructor, even if it is not in the code. If you define a parameterized constructor the default constructor will not bee seen.

Actually when you define the class (non static), the compiler provides this feature thinking that you will be just creating an instance. And if you want any specific operation to perform you surely will be having your own constructor.


Its because when you do not define a constructor the compiler automatically generates a constructor for you which does not take any arguments. When you want something more out of a constructor, you over-ride it. This is NOT function overloading. So the only constructor that the compiler sees now is your constructor which takes an argument. To counter this problem you can pass a default value if the constructor is passed with no value.


A class need a constructor. It is mandatory requirement.

  • If you don't create one, parameterless constructor will be given to you automatically.
  • If you don't want a parameterless constructor, then you need to create your own.
  • If you need both, parameterless constructor and parameter based-constructor you can add them manually.

I will answer you question with another, why do we want always a default parameterless constructor? there are case where this is not desired, so the developer has the control to add or remove it as is need.

참고URL : https://stackoverflow.com/questions/11792207/why-does-the-default-parameterless-constructor-go-away-when-you-create-one-with

반응형