Day*_*mer 1 c++ const vector const-cast
签名vector::push_back是:
void push_back (const value_type& val);
Run Code Online (Sandbox Code Playgroud)
这意味着它有责任不腐败val.
我的功能是:
Result User::addFriend(const User* newFriend)
{
// check that newFriend is valid and is not already a friend
if (newFriend == NULL || isFriend(newFriend)) return FAILURE;
friends_.push_back(newFriend);
friendsNum_++;
return SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
当我编译.c文件时,我得到编译错误:
invalid conversion from 'const User*' to
std::vector User*::value_type
Run Code Online (Sandbox Code Playgroud)
如果push_back承诺不改变val,为什么我们会得到这个错误?
克服错误的正确和清洁方法是什么?也许是const_cast?
谢谢!
User.h:
class User {
...
public:
vector<User*> friends_;
...
}
Run Code Online (Sandbox Code Playgroud)
你正在存储一个指针向量:
std::vector<User*> friends_;
Run Code Online (Sandbox Code Playgroud)
但是,这种方法存在问题.请注意,这些指针不是const User*:任何有访问权限的人friends_都可以自由修改User.
在类型参数vector在这里User*,不是User,这意味着value_type ? User.所以,这一行
void push_back (const value_type& val);
Run Code Online (Sandbox Code Playgroud)
应该这样解释:
void push_back (const User*& val);
Run Code Online (Sandbox Code Playgroud)
请注意,语法在这里有点误导 ; 一个更清晰的方式来看待它是这样的:
void push_back (User *const &val);
Run Code Online (Sandbox Code Playgroud)
该const修改的是左侧:它可以防止改变指针,但它无助于防止潜在的User被改变自身.
由于const只影响指针但不影响User,传入a const User*会违反合同:
Result User::addFriend(const User* newFriend){
…
friends_.push_back(newFriend);
…
}
Run Code Online (Sandbox Code Playgroud)
你不能这样做.由于addFriend承诺不会阻止User被改变,因此将其存储到非const 向量User*中将允许任何有权访问该向量的人修改User它们.
可能的解决方案:
addFriend来User*代替const User*.更好的是:使用引用,除非你有充分的理由不这样做.friends_使用const User*代替User*.更好的是:User直接存储s而不是指针.User.您的代码存在逻辑问题.也就是说,您存储指向可修改对象的指针:
vector<User*> friends_;
Run Code Online (Sandbox Code Playgroud)
然而你的addFriend()方法接受一个指向const对象的指针:
Result User::addFriend(const User* newFriend)
// ^^^^^
{
// stuff..
friends_.push_back(newFriend);
}
Run Code Online (Sandbox Code Playgroud)
那些不排队.原样,push_back必须将您转换const User*为a User*,因此编译错误.应更改这些类型中的一种或另一种.要么friends_必须是vector<const User*>(如果你真的无意修改这些对象),要么addFriend需要User*(如果你这样做).不要用const_cast!