在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;
}