vector :: push_back从const Type*转换为type*

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)
  1. 如果push_back承诺不改变val,为什么我们会得到这个错误?

  2. 克服错误的正确和清洁方法是什么?也许是const_cast

谢谢!

User.h:

class User {
...
public:
    vector<User*> friends_;
...
}
Run Code Online (Sandbox Code Playgroud)

Ruf*_*ind 6

你正在存储一个指针向量:

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它们.

可能的解决方案:

  • 让我们addFriendUser*代替const User*.更好的是:使用引用,除非你有充分的理由不这样做.
  • 更改friends_使用const User*代替User*.更好的是:User直接存储s而不是指针.
  • 制作副本User.


Bar*_*rry 5

您的代码存在逻辑问题.也就是说,您存储指向可修改对象的指针:

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!