Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C+中通过引用与通过值将向量传递到函数中+; 我一直在写一个小项目,只是为了扩充我对C++的知识,我遇到了一个问题。当我接受一个用户名时,我想检查它是否已经被使用。如果使用了该特定用户名,我会将问题重新打印给用户。它在第一个循环中运行良好,但在那之后,它将接受任何内容,即使它确实存在于用户向量中 bool verify(char * a, vector<User> b){ 14 for(int i = 0; i < b.size(); i++){ 15 if(strcmp(a, b[i].getUsername()) == 0){ 16 return false; 17 } 18 } 19 return true; 20 } 21 22 int main(){ 23 24 vector<User> users; 25 26 User us1((char *)"foo", (char *)"bar"); 27 users.push_back(us1); 28 29 30 do{ 31 cout << "Enter Username: "; 32 scanf(" %s", username); 33 34 35 } while(!verify(username, users)); 36 37 return 0; 38 } bool验证(字符*a,向量b){ 14表示(int i=0;i密码=strdup(密码); 12 13 } 14 15用户::~User(){ 16 17删除用户名; 18删除密码; 19 20 } 21 22无效用户::getMessage(){ 23 24 CUT我强烈推荐在任何可能的情况下使用C++功能,它通常更容易阅读,而且不易出错。_C++_Vector_Reference - Fatal编程技术网

在C+中通过引用与通过值将向量传递到函数中+; 我一直在写一个小项目,只是为了扩充我对C++的知识,我遇到了一个问题。当我接受一个用户名时,我想检查它是否已经被使用。如果使用了该特定用户名,我会将问题重新打印给用户。它在第一个循环中运行良好,但在那之后,它将接受任何内容,即使它确实存在于用户向量中 bool verify(char * a, vector<User> b){ 14 for(int i = 0; i < b.size(); i++){ 15 if(strcmp(a, b[i].getUsername()) == 0){ 16 return false; 17 } 18 } 19 return true; 20 } 21 22 int main(){ 23 24 vector<User> users; 25 26 User us1((char *)"foo", (char *)"bar"); 27 users.push_back(us1); 28 29 30 do{ 31 cout << "Enter Username: "; 32 scanf(" %s", username); 33 34 35 } while(!verify(username, users)); 36 37 return 0; 38 } bool验证(字符*a,向量b){ 14表示(int i=0;i密码=strdup(密码); 12 13 } 14 15用户::~User(){ 16 17删除用户名; 18删除密码; 19 20 } 21 22无效用户::getMessage(){ 23 24 CUT我强烈推荐在任何可能的情况下使用C++功能,它通常更容易阅读,而且不易出错。

在C+中通过引用与通过值将向量传递到函数中+; 我一直在写一个小项目,只是为了扩充我对C++的知识,我遇到了一个问题。当我接受一个用户名时,我想检查它是否已经被使用。如果使用了该特定用户名,我会将问题重新打印给用户。它在第一个循环中运行良好,但在那之后,它将接受任何内容,即使它确实存在于用户向量中 bool verify(char * a, vector<User> b){ 14 for(int i = 0; i < b.size(); i++){ 15 if(strcmp(a, b[i].getUsername()) == 0){ 16 return false; 17 } 18 } 19 return true; 20 } 21 22 int main(){ 23 24 vector<User> users; 25 26 User us1((char *)"foo", (char *)"bar"); 27 users.push_back(us1); 28 29 30 do{ 31 cout << "Enter Username: "; 32 scanf(" %s", username); 33 34 35 } while(!verify(username, users)); 36 37 return 0; 38 } bool验证(字符*a,向量b){ 14表示(int i=0;i密码=strdup(密码); 12 13 } 14 15用户::~User(){ 16 17删除用户名; 18删除密码; 19 20 } 21 22无效用户::getMessage(){ 23 24 CUT我强烈推荐在任何可能的情况下使用C++功能,它通常更容易阅读,而且不易出错。,c++,vector,reference,C++,Vector,Reference,现在在你的代码中有很多问题,你是对的,你的主要问题是没有正确处理三的规则 您的User类执行动态分配,但不定义copyconstructor和assignment运算符。对于显示问题的简单代码段,请查看该代码段。它只复制地址,而不复制指向的实际数据,因此,一旦删除第一个副本,所有其他副本都无效 您还存在其他问题,strdup是不可移植的,它不是C标准的一部分。它是POSIX标准的一部分,因此很可能仅在实现该标准的系统上可用。此外,它是一个C函数,使用malloc分配内存,您应该删除它从C返回fr

现在在你的代码中有很多问题,你是对的,你的主要问题是没有正确处理三的规则

您的
User
类执行动态分配,但不定义copyconstructor和assignment运算符。对于显示问题的简单代码段,请查看该代码段。它只复制地址,而不复制指向的实际数据,因此,一旦删除第一个副本,所有其他副本都无效

您还存在其他问题,
strdup
是不可移植的,它不是C标准的一部分。它是POSIX标准的一部分,因此很可能仅在实现该标准的系统上可用。此外,它是一个C函数,使用
malloc
分配内存,您应该删除它从C返回
free
的指针,而不是C++中的<代码>删除<代码> > < /P> <> p>也有一个原因,即C++中的字符串文字是代码> const char []/COD>,实际上在C中它们是<代码> char []但不允许编辑它们,因此实际上也是常量。这是因为允许编译器将字符串文本放入可执行文件的只读位置。因此,不要将字符串文本强制转换为
char*
使函数正确地采用
const char*


处理这些指针的事情都很烦人,因为C++使它更容易用<代码> STD::String >,我建议用它代替:

class User {
  private:
    std::string userName;
    std::string password;

    User(const std::string &userName, const std::string & passWord);
    std::string getUsername();
    std::string getPassword();
    void printUser();
};

User::User(const std::string & userName, const std::string & passWord) {
  this->userName = userName;
  this->passWord = passWord;
}

std::string User::getUsername() {
  return userName;
}

std::string User::getPassword() {
  return passWord;
}

// etc...

这里C++自动处理所有的复制和删除逻辑,并且不必处理烦人的指针。

< P>我强烈推荐在任何可能的情况下使用C++功能,通常更可读,更容易出错。 现在在你的代码中有很多问题,你是对的,你的主要问题是没有正确处理三的规则

您的
User
类执行动态分配,但不定义copyconstructor和assignment运算符。对于显示问题的简单代码段,请查看该代码段。它只复制地址,而不复制指向的实际数据,因此,一旦删除第一个副本,所有其他副本都无效

您还存在其他问题,
strdup
是不可移植的,它不是C标准的一部分。它是POSIX标准的一部分,因此很可能仅在实现该标准的系统上可用。此外,它是一个C函数,使用
malloc
分配内存,您应该删除它从C返回
free
的指针,而不是C++中的<代码>删除<代码> > < /P> <> p>也有一个原因,即C++中的字符串文字是代码> const char []/COD>,实际上在C中它们是<代码> char []但不允许编辑它们,因此实际上也是常量。这是因为允许编译器将字符串文本放入可执行文件的只读位置。因此,不要将字符串文本强制转换为
char*
使函数正确地采用
const char*


处理这些指针的事情都很烦人,因为C++使它更容易用<代码> STD::String >,我建议用它代替:

class User {
  private:
    std::string userName;
    std::string password;

    User(const std::string &userName, const std::string & passWord);
    std::string getUsername();
    std::string getPassword();
    void printUser();
};

User::User(const std::string & userName, const std::string & passWord) {
  this->userName = userName;
  this->passWord = passWord;
}

std::string User::getUsername() {
  return userName;
}

std::string User::getPassword() {
  return passWord;
}

// etc...

< C++ >自动处理所有复制和删除逻辑,不必处理烦琐的指针。

讨论使用<代码> STD::String >,OP代码中的基本问题是,对于<代码>用户< /Cuff>类,缺少一个用户定义的复制构造函数。ode>userName和

passWord
字段,导致两个向量(主
main
中的向量和为
verify
功能创建的向量)指向相同的分配内存地址。当
验证
返回时,该内存被删除,将
用户
留在
main
中的向量中,指针悬空(指向已释放的内存)

相反,使用引用可以避免这种删除,并保持原始向量不变


这就是为什么现在不应该在代码中使用原始指针的原因之一。

除了使用
std::string
的所有讨论之外,OP代码中的基本问题是缺少用户定义的
user
类的复制构造函数。默认的复制构造函数只会复制
userName
passWord
f中的值IELD,导致两个向量(主
中的向量和为
验证
功能创建的向量)指向相同的分配内存地址。当
验证
返回时,该内存被删除,主
中向量中的
用户
带有悬空指针(指向释放的内存)

使用参考仪器
#include <vector>
#include <string>
#include <iostream>
#include <cstdio>
#include <cstring>

struct User {
    std::string name, game;
    User(const char* nam, const char* gam) : name(nam), game(gam) {}
    const char* getUsername() const {
        return name.c_str();
    }
};

bool verify(char * a, std::vector<User> b) {
    for (int i = 0; i < b.size(); i++) {
        if (std::strcmp(a, b[i].getUsername()) == 0) {
            return false;
        }
    }
    return true;
}

int main(){    
    std::vector<User> users;

    User us1("foo", "bar");
    users.push_back(us1);

    char username[100];

    do {
        std::cout << "Enter Username: ";
        std::scanf(" %50s", username);
    } while(!verify(username, users));

    return 0;
}
for (auto u : b) {
    if (strcmp(a, u.getUsername()) == 0)
        return false;
}
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

struct User {
    std::string name, game;
    User(const char* nam, const char* gam) : name(nam), game(gam) {}
    const std::string& getUsername() const {
        return name;
    }
};

int main(){
    std::vector<User> users;
    users.push_back({"foo","bar"});
    std::string username;

    do {
        std::cout << "Enter Username: ";
        std::cin >> username;
    } while(std::any_of(users.begin(), users.end(),
            [username](const auto& u){ return u.getUsername() == username; }));

    return 0;
}