current_user指针在System.cpp的函数内工作,但之后重置。当current_user在switch语句中调用时,它在函数createUser(string name)中设置时似乎在本地更新。但是,当我尝试在函数外部调用它时,它似乎根本没有更新。不完全确定发生了什么。
Main.cpp的
#include <iostream>
#include "System.h"
#include "User.h"
using namespace std;
int main()
{
System s;
s.run();
// Works
User a("Test");
User b("Test 2");
User c("Test 3");
User* current = &a;
cout << "The current user is: " << current->getName() << endl;
current = &b;
cout << "Now it's: " << current->getName() << endl;
current = &c;
cout << "The final current user is: " << current->getName() << endl;
// Does not work
cout << "Current user: " << s.getCurrentUser()->getName() << endl;
}
System.h
#ifndef SYSTEM_H
#define SYSTEM_H
#include "User.h"
#include "Group.h"
#include "MessageBuffer.h"
#include "Banner.h"
#include <iostream>
#include <vector>
class System
{
public:
System();
char validInput(std::string inputIn);
bool validUsername(std::string nameIn);
bool userExists(std::string nameIn);
void createUser(std::string nameIn);
void run();
User* getCurrentUser();
private:
User* current_user;
std::vector<User> user_list;
std::vector<Group> group_list;
};
#endif // SYSTEM_H
System.cpp
// Program 1: TigerBook Social Network
// File: System.cpp
// Description: Class Implimentation of the System Class. Instantiates objects that must be initialized and handles
// basic user screw-ups (choosing and option out of bounds).
#include <iostream>
#include "System.h"
using namespace std;
// Function: Default System Constructor
// Inputs: None
// Description: Default constructor for the class.
System::System()
{
}
User* System::getCurrentUser()
{
return current_user;
}
// Function: validInput
// Inputs: string inputIn
// Outputs: char value of input at 0
// Description: Determines whether the input is valid.
char System::validInput(string inputIn)
{
if (inputIn.length() == 1)
{
return inputIn[0];
}
else
{
return '0';
}
}
// Function: validUsername
// Inputs: string username
// Outputs: true if valid, false if not
// Description: Determines whether the username is valid
bool System::validUsername(string nameIn)
{
if (nameIn.empty() || nameIn.length() < 2 || (nameIn.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") != string::npos))
{
cerr << "\n\t*** ERROR: Invalid user name, please try again! ***" << endl;
return false;
}
else
{
return true;
}
}
// Function: userExists
// Inputs: string username
// Outputs: true if exists, false if not
// Description: Determines whether the username exists in user_list.
bool System::userExists(string nameIn)
{
return false;
}
// Function: createUser
// Inputs: string username
// Outputs: void
// Description: Creates new user and adds it to user_list.
void System::createUser(string nameIn)
{
User u(nameIn);
user_list.push_back(u);
current_user = &u;
}
// Function: run
// Inputs: None
// Outputs: void
// Description: Program driver, handles basic user input and screw-ups
void System::run()
{
//current_user = NULL;
Banner banner("The TigerBook Social Network!");
cout << banner.getBanner() << endl;
bool quit = false;
string input;
while(!quit)
{
cout << "\nCreate new user (n), Broadcast (b), Multicast (m), Unicast (u), Wall page (w), Home page (h), Create new group (g), " << endl;
cout << "Join a group (j), Switch user (s), Quit (q)\n" << endl;
cout << "Choose an option: ";
getline(cin, input);
if (current_user == NULL && (input != "N" && input != "n" && input != "Q" && input != "q"))
{
cerr << "\n\t*** ERROR: There is no current user, please create a new user! ***" << endl;
continue;
}
switch (validInput(input))
{
// Create new user
case 'N':
case 'n':
{
string username;
cout << "\nPlease enter user name: ";
getline(cin, username);
if (!validUsername(username))
{
continue;
}
else if (userExists(username))
{
cerr << "\n\t*** ERROR: The user \"" + username + "\" already exists, please try again! ***" << endl;
continue;
}
else
{
createUser(username);
cout << "\nCurrent user: " << getCurrentUser()->getName() << endl; // test current_user
}
break;
}
case 'B':
case 'b':
{
break;
}
case 'M':
case 'm':
{
break;
}
case 'U':
case 'u':
{
break;
}
case 'W':
case 'w':
{
break;
}
case 'H':
case 'h':
{
break;
}
case 'G':
case 'g':
{
break;
}
case 'J':
case 'j':
{
break;
}
case 'S':
case 's':
{
break;
}
case 'Q':
case 'q':
{
quit = true;
banner.setBanner("Thank you for using TigerBook Social Network!");
cout << banner.getBanner() << endl << endl;
break;
}
default:
{
cerr << "\n\t*** ERROR: Invalid input, please try again! ***" << endl;
}
} // End of switch statement
} // End of loop
}
User.h
#ifndef USER_H
#define USER_H
#include <string>
class User
{
public:
User();
User(std::string nameIn);
std::string getName();
void setName(std::string nameIn);
private:
std::string name;
};
#endif // USER_H
User.cpp
// Program 1: TigerBook Social Network
// File: User.cpp
// Description: Class implementation for User class
#include "User.h"
using namespace std;
// Constructor (Default)
User::User()
{
//ctor
}
// Constructor
// Inputs: string that sets name
// Description: Constructs user object and assigns its name.
User::User(string nameIn)
{
name = nameIn;
}
// Function: setName
// Inputs: string that sets name
// Outputs: void
// Description: Sets name of user object.
void User::setName(string nameIn)
{
name = nameIn;
}
// Function: getName
// Inputs: none
// Outputs: Name of user
// Description: Returns the name of the user object.
string User::getName()
{
return name;
}
答案 0 :(得分:1)
你有:
void System::createUser(string nameIn)
{
User u(nameIn);
user_list.push_back(u);
current_user = &u;
}
这里,您存储指向局部变量的指针。函数返回后,指针变为悬空指针。在函数返回后使用current_usr
访问对象是导致未定义的行为的原因。
您可以使用:
void System::createUser(string nameIn)
{
User u(nameIn);
user_list.push_back(u);
current_user = &(user_list.back());
}
即便是非常脆弱。如果您仔细管理user_list
中的对象,它将起作用。
更好的选择是根本不存储指向对象的指针。例如,您可以使用:
User* System::getCurrentUser()
{
if ( user_list.empty() )
{
return nullptr;
}
return &(user_list.back());
}