在 C++ 中初始化数组
我正在尝试初始化一个对象数组:
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")};
但是当我尝试这样做时,它会不断尝试调用我的复制构造函数而不是重载的构造函数。有什么想法可以解决这个问题吗?
有问题的 2 个构造函数是:
SinglyLinkedList(string course); //Constructor
SinglyLinkedList(SinglyLinkedList & otherObj); //Copy Constructor
我需要复制构造函数来处理其他事情,所以我无法删除它。
感谢您的帮助!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
看来您的编译器已严重损坏。您的复制构造函数是使用非常量引用参数声明的。这样的复制构造函数不能用临时对象作为参数来调用,因为非常量引用不能绑定到临时对象。
您的初始值设定项是临时对象,这意味着这里绝对无法调用复制构造函数。如果您的编译器这样做,则意味着它已损坏,或者您正在使用某些设置使其以奇怪的不合规方式运行。您使用哪个编译器?
这是答案的第一部分。
第二部分是大括号括起来的初始化列表在 C++ 中被解释为复制初始化。换句话说,在这种情况下必须调用复制构造函数。没有办法解决这个问题(稍后可以优化调用,但构造函数在任何情况下都必须可用)。在这方面,您的编译器表现“正确”,即它尝试调用复制构造函数,正如它应该的那样。除此之外,正如我上面所说,在您的情况下,它应该发出错误(因为复制构造函数不可调用),而不是安静地调用它。
最后是答案的第三部分。
您是说复制构造函数被称为而不是转换构造函数。实际上,两者都被调用。如果你仔细观察,你就会发现。首先,调用 conversion 构造函数,以便从您提供的字符串创建“SinglyLinkedList”类型的中间临时对象(这也涉及构造一个临时“std::string”对象),并且然后调用复制构造函数以从临时数组元素初始化数组元素(这对于数组中的每个元素都会发生)。这就是 C++ 中的情况,假设您的复制构造函数已正确声明,即使用 const 引用参数。但对于非常量引用参数,复制构造函数不可调用,并且代码格式错误。
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", i.e. 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, i.e. with a const reference parameter. But with non-const reference parameter, the copy-constructor is not callable and the code is ill-formed.
当您有单参数构造函数时,请始终将它们声明为
显式
,例如,这样您就有更好的机会调用正确的构造函数。
另一方面,编译器正在搜索的构造函数是
SinglyLinkedList( const char* )
。尝试直接创建字符串实例,例如SinglyLinkedList( string("CSCE101") )
When you have single argument constructors always declare them
explicit
, e.g.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, e.gSinglyLinkedList( string("CSCE101") )
您调用的构造函数的签名是
SinglyLinkedList( char const * )
您没有提供所以要么生成一个采用 char const* 的构造函数,要么将它们称为 SinglyLinkedList(string( "CSCE101" ))
没有从 char* 到 std::string 的隐式转换 - 所以您的编译器必须查看哪个重载匹配,并找到匹配的 SinglyLinkedList。
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.
您可能想尝试将构造函数声明更改为:
然后添加赋值运算符和析构函数:
我很惊讶它竟然能够编译,因为如果没有 const,两个构造函数应该是不明确的。
You might want to try changing your constructor declarations to:
Then add in the assignment operator and destructor:
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.