C++中Vector存储Horse对象循环后数据丢失及类成员访问问题
Hey there! Let's tackle your two issues one by one—they're common pitfalls for new C++/OOP developers, so don't worry, we'll get you sorted.
1. Fixing Vector Data Loss
The root cause here is how your Horse default constructor is written. Right now, you're creating local variables inside the constructor instead of initializing the class's actual member variables:
Horse() // 默认构造函数 { std::string name = " "; // This is a LOCAL variable, not the class member! std::string rider = " "; // Same here—local, not class member int maxRunningDistPerSecond = 100; int distanceTraveled = 0; int racesWon = 0; };
These local variables "shadow" (hide) your class's real members, meaning your Horse objects' core variables are never properly set up (even though std::string defaults to empty, this isn't what you intended). While your setName and setRider methods do assign values to the class members later, this constructor mistake can lead to unexpected behavior like the data loss you're seeing.
The Fix:
Rewrite your default constructor to initialize the class's member variables directly. Two solid approaches:
Option 1: Use a Member Initializer List (Recommended for C++)
This is the most efficient and readable way to initialize class members:
Horse() : name(" "), rider(" "), maxRunningDistPerSecond(100), distanceTraveled(0), racesWon(0) {}
Option 2: Assign Members Inside the Constructor Body
If the initializer list feels confusing, you can assign values directly to the class members (no local variable declarations):
Horse() { name = " "; // Now this refers to the class's member variable rider = " "; maxRunningDistPerSecond = 100; distanceTraveled = 0; racesWon = 0; }
Once you fix the constructor, your vector<Horse> will retain the values you set in the loop—calling HorseStable[0].printName() will return the first horse's name as expected.
2. Accessing Private Class Members Properly
The key here is understanding encapsulation: private members should only be accessed by the class itself or trusted functions. Your mistake is trying to pass a private member from main to displayHorse—you don't need to do that if displayHorse is a member function of Horse.
The Fix: Make displayHorse a Member Function
Update your Horse class to include displayHorse as a public member function. Since it's part of the class, it can directly access all private members:
Step 1: Declare the Function in the Horse Class
class Horse { private: std::string name; std::string rider; int maxRunningDistPerSecond; int distanceTraveled; int racesWon; public: // Your existing constructors, setName, printName, etc. void displayHorse(); // Add this declaration };
Step 2: Implement the Function
void Horse::displayHorse() { // You can directly access all private members here std::cout << "Horse Name: " << name << std::endl; std::cout << "Rider: " << rider << std::endl; std::cout << "Max Running Distance/Second: " << maxRunningDistPerSecond << std::endl; std::cout << "Distance Traveled: " << distanceTraveled << std::endl; std::cout << "Races Won: " << racesWon << std::endl; }
Step 3: Call It from Main
Now in main, you can call it without passing any private members:
HorseStable[0].displayHorse();
Alternative: If displayHorse Needs to Be a Global Function
If for some reason you can't make displayHorse a member function, you have two options:
- Add Getter Methods: Create public methods to retrieve private values (e.g.,
int getDistanceTraveled() const { return distanceTraveled; }), then call these from your globaldisplayHorse. - Declare as a Friend: Add
friend void displayHorse(const Horse&);to yourHorseclass, which lets the global function access private members directly.
Sticking with member functions is the cleanest approach for OOP, though.
内容的提问来源于stack exchange,提问作者prest

