简体   繁体   中英

Initializing an array in C++

I am trying to initialize an array of objects:

SinglyLinkedList offeredClasses[22] = {SinglyLinkedList("CSCE101"),SinglyLinkedList("CSCE101L"),SinglyLinkedList("CSCE150E"),SinglyLinkedList("CSCE150EL"),SinglyLinkedList("CSCE150EM"),SinglyLinkedList("CSCE150EML"),SinglyLinkedList("CSCE155"),SinglyLinkedList("CSCE155H"),SinglyLinkedList("CSCE156"),SinglyLinkedList("CSCE230"),SinglyLinkedList("CSCE230L"),SinglyLinkedList("CSCE235"),SinglyLinkedList("CSCE251"),SinglyLinkedList("CSCE310"),SinglyLinkedList("CSCE322"),SinglyLinkedList("CSCE361"),SinglyLinkedList("CSCE351"),SinglyLinkedList("CSCE451"),SinglyLinkedList("CSCE423"),SinglyLinkedList("CSCE428"),SinglyLinkedList("CSCE486"),SinglyLinkedList("CSCE487")};

but when I try to do this it keeps trying to call my copy constructor instead of an overloaded constructor. Any ideas to fix this?

the 2 constructors in question are:

SinglyLinkedList(string course); //Constructor
SinglyLinkedList(SinglyLinkedList & otherObj); //Copy Constructor

I need the copy constructor for other things so I can't remove it.

Thanks for your help!

It appears theat your compiler is seriously broken. Your copy-constructor is declared with a non-const reference parameter. Such a copy-constructor cannot be invoked with temporary object as an argument, since a non-const reference cannot be bound to a temporary object.

Your initializers are temporary objects, meaning that there's absolutely no way a copy-constructor can be called here. If your compiler does it, it means that it is either broken or that you are using some set of settings that make it behave in a weird non-compliant way. Which compiler are you using?

That's the first part of the answer.

The second part is that brace-enclosed initializer lists are interpreted as copy-initialization in C++. In other words, the copy-constructor must be called in this case. There's no way around it (the call can be later optimized away, but the constructor must be available in any case). In this regard, your compiler is behaving "correctly", ie it makes an attempt to call the copy-constructor, as it should. Except that, as I said above, in your case it should issue an error (since the copy-constructor is not callable) instead of quetly calling it.

And, finally, the third part of the answer.

You are saying that the copy-constructor is called instead of the conversion constructor. In reality, both are called. If you look carefully, you'll see it. Firstly, the conversion constructor is called in order to create an intermediate temporary object of 'SinglyLinkedList' type from the string you supplied (that involves constructing a temporary 'std::string' object as well), and then the copy-constructor is called in order to initialize the array element from the temporary (this happens for each element in the array). This is how it should be in C++, assuming your copy-constrcutor is declared properly, ie with a const reference parameter. But with non-const reference parameter, the copy-constructor is not callable and the code is ill-formed.

When you have single argument constructors always declare them explicit , eg

explicit SinglyLinkedList(string course); //Constructor
explicit SinglyLinkedList(SinglyLinkedList & otherObj); //Copy Constructor

That way you have better chance of calling the right constructor.

On the other hand, the constructor compiler is searching for is SinglyLinkedList( const char* ) . Try to create string instance directly, eg SinglyLinkedList( string("CSCE101") )

The signature of the construcors you are calling is SinglyLinkedList( char const * )

Which you have not provided So either produce a constructotr taking char const* or call them as SinglyLinkedList(string( "CSCE101" ))

There is no implicit conversion from char* to std::string - so your the compiler has to see which overload matches and it finds matching SinglyLinkedList.

You might want to try changing your constructor declarations to:

explicit SinglyLinkedList(std::string const& name);
SinglyLinkedList(SinglyLinkedList const& other);

Then add in the assignment operator and destructor:

~SinglyLinkedList();
SinglyLinkedList& operator=(SinglyLinkedList const& other);

I'm surprised that it is compiling at all since without the const s the two constructors should be ambiguous.

What do you need the copy constructor for that ISN'T copy construction? If you need it for something else then you need to change that other thing. It makes for really hard to understand code, even if you ignore problems like you are currently suffering. This is the same problem that people cause in maths libraries by doing things like overloading operator^ to do a cross-product.

Use things for what they are meant to be used for and prevent later problems while making your code many times more maintainable.

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