0
0
0142016-02-13 00:09:50
C++ / C#
014, 2016-02-13 00:09:50

Why doesn't the overloaded class constructor work?

class String
{
private:
    strCount *psc;
public:
    String()
    {
        psc = new strCount("NULL");
    }

    String(String &S)
    {
        psc = S.psc;
        (psc->count)++;
    }

    String(const char *s)
    {
        psc = new strCount(s);
    }

If you initialize the object like this:
String s1;
String s2 = s1;

That the compiler does not swear.
And if so:
String s1 = "Нас обманули, расходимся."
then the compiler says that there is a mismatch, but there is a constructor that takes const Char *, why does this happen?
Of course, I understand that it is necessary to initialize with brackets (), and in C ++ 11 already with curly {}, but still, why such behavior?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
MiiNiPaa, 2016-02-13
@MiiNiPaa

Because it's copy -initialization . For it to work, you need a copy constructor that can take temporary objects as a parameter. (even though they won't be called thanks to copy-elision )
Edit: en.cppreference.com/w/cpp/language/copy_initialization

If T is a class type, and the type of other is different, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T ( or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a prvalue temporary if a converting constructor was used, is then used to direct-initialize the object. The last step is usually optimized outand the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used.
Roughly speaking, first what is on the right is implicitly cast to the type on the left (using the constructor) and then used to initialize the variable using the move or copy constructor.

M
Mercury13, 2016-02-13
@Mercury13

I'll try to explain this in simpler terms.
The text String s3 = "Нас обманули, расходимся.";means this. We create a temporary string "We were deceived, we part ways" and then assign it to our s3. Of course, the compiler will optimize this later, but this is the semantics of the language, and it must be followed.
There are two ways to pass a temporary object to a function. Any: even a simple one, even a constructor, even an operation =.
The first is a constant reference: String(const String &S).
The second way from C++11 is temporary reference: String(String &&S).
Because of these temporary objects, the copy constructor and the "assign" operation, in a good way, should take a const reference. Here is a similar example with the "assign" operation.

class String
{
public:
    String() {}
    String& operator= (String& s) { return *this; }
};
String operator+ (String a, String b) { return String(); }

int main()
{
    String s1;
    String s2 = s1;
    String s4;
    s4 = s1 + s2;
}

Resolved String& operator= (const String& s).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question