如何在另一类构造函数中使用其他类成员?Player类代码问题咨询
Fixing Your Player Class Implementation in C++
Let's walk through the issues in your code first, then fix it up with proper C++ practices.
First, the Core Problems in Your Current Code
- Inheritance Misuse: Public inheritance implies an "is-a" relationship, but a
Playerisn't a type ofCave. This is a classic design mistake—you want aPlayerto use aCave, not be one. We'll fix this with composition (a "has-a" relationship) instead. - Pointless Parameter Assignment: In your
Playerconstructor, you're assigning&rooms[0]to the parameterplyr. This only modifies the local copy of the pointer inside the constructor, not the variable you passed in from outside. Plus, your initializer list already setsp_ptrto the originalplyrvalue, making that assignment totally useless. - Undefined Behavior Risk: If you ever use the default
Caveconstructor, theroomsvector will be empty. Taking&rooms[0]in that case is undefined behavior (it's accessing out-of-bounds memory).
Corrected Implementation with Composition (Recommended)
This is the cleanest, most logical approach since a player has a cave to explore, rather than being a cave itself.
#include <vector> // First define the Cave class as you did, with a minor safety tweak class Cave { private: int no_of_rooms; public: std::vector<int> rooms; // Constructor to populate rooms with random values Cave(int r) : no_of_rooms{ r } { for (int i = 0; i < no_of_rooms; ++i) { // Assuming randint() is your function that returns [1, no_of_rooms] rooms.push_back(randint(1, no_of_rooms)); } } // Default constructor: initialize room count to 0 for safety Cave() : no_of_rooms{ 0 } {}; }; // Player class now contains a Cave instance (composition) class Player { private: int* p_ptr = nullptr; Cave player_cave; // Player "has-a" Cave public: // Constructor: create a Cave with the given room count, then point to the first room Player(int room_count) : player_cave(room_count) { // Only set the pointer if rooms isn't empty if (!player_cave.rooms.empty()) { p_ptr = &player_cave.rooms[0]; } } // Optional: Constructor that takes an existing Cave instance Player(const Cave& existing_cave) : player_cave(existing_cave) { if (!player_cave.rooms.empty()) { p_ptr = &player_cave.rooms[0]; } } // Helper method to get the current room value (for testing/usage) int get_current_room() const { return p_ptr ? *p_ptr : -1; // Return -1 if pointer is invalid } };
If You Must Use Inheritance (Not Recommended)
If for some reason you need Player to inherit from Cave, fix the constructor to properly initialize the parent class and set your pointer correctly:
class Player : public Cave { private: int* p_ptr = nullptr; public: // First call the Cave constructor to initialize rooms, then set p_ptr Player(int room_count) : Cave(room_count) { if (!rooms.empty()) { p_ptr = &rooms[0]; } } };
Key Takeaways
- Always prefer composition over inheritance when the relationship is "has-a" instead of "is-a"—it makes your code more flexible and easier to maintain.
- Never modify function parameters expecting the change to affect the caller (unless you use references or pointers-to-pointers, which isn't needed here).
- Always add safety checks for empty containers before accessing their elements or addresses.
内容的提问来源于stack exchange,提问作者user539249
相关产品推荐
相关产品推荐

