简体   繁体   中英

Why can I assign struct with a pointer?

Why does it even compile?

struct UE{
    UE(bool a = true) {  };
//  UE(){}; // if UE took no initial args and called below, gcc will complain.
};
class VA {
    protected:
            UE ue;
    public:
            VA();
};
VA::VA()
{
    ue = new UE(true); // ???why???
//  ue = new UE(); // will complain
}

I tried with gcc (GCC) 4.6.2. How can I assign a struct with a pointer?

You're hitting the fact that you didn't mark your constructor as explicit , and thus it can be used for implicit conversions.

new UE(true) returns a pointer. All pointers can be implicitly converted to bool , resulting in true if they are non-null. UE can be implicitly constructed from a bool . So in effect, the pointer returned by new is converted to bool , which is converted to UE using your constructor, and then the copy assignment operator of UE is called. Of course, the memory allocated by new is leaked.

The take-home message is: always mark your single-argument constructors as explicit unless you actually want them to be usable for implicit conversions. By "single-argument constructor," I mean one which can be called with a single argument. Either because it has one parameter, or it has more and all parameters after the first have default arguments.

There is an implicit conversion from any pointer to bool . Hence this code is implicitly calling the single argument constructor after converting the pointer to a bool value

One way to fix this is to make the single parameter constructor explicit.

struct UE{
    explicit UE(bool a = true) {  };
};

This will prevent the code from compiling unless the constructor is explicitly invoked

Any scalar type can be converted to boolean value true or false depending on whether its value is equal to zero or not..

In this statement

ue = new UE(true); 

the implicitly defined by the compiler copy assignment operator is called. As expression new UE( true ) is not equal to zero then it can be converted implicitly to boolean value true. Class UE has conversion constructor

UE(bool a = true);

that converts an object of type bool to an object of type UE.

To prevent such usage you should define the constructor as explicit

explicit UE(bool a = true);

If you mark you constructor explicit this won't work:

explicit UE( bool a = true) {  };

this is because there is an implicit conversion from the pointer to a bool, we can see this is allowed from draft C++ standard section 4.12 Boolean conversions says ( emphasis mine ):

A prvalue of arithmetic, unscoped enumeration, pointer , or pointer to member type can be converted to a prvalue of type bool.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM