programing tip

생성자에서 암시 적 변환을 피합니다.

itbloger 2021. 1. 6. 07:51
반응형

생성자에서 암시 적 변환을 피합니다. '명시 적'키워드는 여기에서 도움이되지 않습니다.


explicit키워드를 사용하여 생성자의 암시 적 변환을 피할 수 있습니다. 따라서 이제 같은 전환을 A a1 = 10;피할 수 있습니다.

하지만 여전히 초기화 할 수 있습니다 A a1 = A(20.2);. 정수를 매개 변수로 전달하는 경우에만 객체를 만들 수 있도록 객체 생성을 비활성화하려면 어떻게해야 A a1 = A(10)합니까?

#include <iostream>

class A
{
public:
    explicit A(int a)
    {
        num = a;
    }

    int num;
};

int main()
{
    A a1 = A(10.0);
    std::cout << a1.num;
    return 0;
}

다음을 수행 할 수 있습니다 delete A::A(<anything not an int>);.

struct A
{
    explicit A(int a)
    : num(a)
    {}

    template<class T>
    A(T) = delete;

    int num;
};

int main()
{
    //A a1=A(10.0); // error: use of deleted function 'A::A(T) [with T = double]'
    A a2 = A(10); // OK
    (void) a2;
}

데모 : https://coliru.stacked-crooked.com/a/425afc19003697c9


이를 달성하는 방법은 더 잘 일치하는 다른 생성자를 제공 한 다음 delete오류가 발생하도록하는 것입니다. 수업을 위해

template <typename T>
A(T) = delete;

클래스가 아닌 다른 것으로부터 생성되는 것을 막을 것입니다. int


You can circumvent this problem by using braced initialization. For example:

struct A {
  A(int _a) : a(_a) {}
  int a;
};

A a{5}; // ok
A b{1.123}; // compile error

Proof


I just want to add that the A(double) = delete is a C++11 addition.

If for whatever reason you cannot use this relatively new construct, you can simply declare it as private as this:

class A{
  public:
    A(int);
  private:
    A(double);
}

To avoid int->double conversions everywhere, not only in your case. With g++ you can use -Wconversion -Werror. Note that it'll be allowed in your particular case, because the compiler understands that 10.0 is literal, but it will fail compilation for:

class A
{
public:
    explicit A(int a)
    {
        num = a;
    }

    int num;
};

int main()
{
    double x = 10;
    A a1 = A(x);
    static_cast<void>(a1);
    return 0;
}

Compiler explorer


Explicitly delete the constructor for double (possibly add float):

A(double) = delete;

You should use the -Wconversion flag of gcc, that will generate a warning when implicitly casting a float to an int. Add -Werror to transform this warning (all in fact) into an error.

ReferenceURL : https://stackoverflow.com/questions/57293752/avoiding-implicit-conversion-in-constructor-the-explicit-keyword-doesnt-help

반응형