You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++:如何将子类数据存入基类vector并以子类类型遍历

Answer

Absolutely feasible! This is a classic use case for C++ polymorphism with smart pointers. Let's break down how to move your AccountsStruct data into the inherited Data vector, plus how to safely iterate over it later as AccountsStruct instances:

1. Populate the Data vector from your loaded vector<AccountsStruct>

Since AccountsStruct publicly inherits from DataStruct, a std::unique_ptr<AccountsStruct> can be implicitly converted to std::unique_ptr<DataStruct>. You can transfer ownership of each AccountsStruct object into the Data vector using either a loop or std::transform for conciseness:

// Assume you have your loaded data stored here:
std::vector<AccountsStruct> loadedAccounts;

// Option 1: Range-based for loop
for (auto& account : loadedAccounts) {
    // Use std::move to avoid copying the entire struct
    Data.push_back(std::make_unique<AccountsStruct>(std::move(account)));
}

// Option 2: More concise with std::transform
std::transform(
    loadedAccounts.begin(), loadedAccounts.end(),
    std::back_inserter(Data),
    [](AccountsStruct&& acc) {
        return std::make_unique<AccountsStruct>(std::move(acc));
    }
);

Important: Make sure DataStruct has a virtual destructor! Without it, the unique_ptr won't call the correct destructor for AccountsStruct when cleaning up, leading to memory leaks and undefined behavior. Define it like this:

struct DataStruct {
    virtual ~DataStruct() = default; // Critical for safe polymorphism
    // Add other virtual methods if needed for your use case
};

2. Iterate over Data as AccountsStruct instances

To access the AccountsStruct-specific members, you'll need to safely downcast the DataStruct pointers. The safest way to do this is with dynamic_cast, which performs a runtime type check to ensure the conversion is valid:

for (const auto& dataPtr : Data) {
    // Attempt to cast the base pointer to AccountsStruct*
    if (auto* account = dynamic_cast<AccountsStruct*>(dataPtr.get())) {
        // Now you can access all AccountsStruct members safely
        std::cout << "Account ID: " << account->id << ", Username: " << account->username << "\n";
    } else {
        // Handle unexpected data types (though this shouldn't happen if LoadTable is properly implemented)
        std::cerr << "Warning: Found non-AccountsStruct data in Accounts table!\n";
    }
}

If you're 100% certain that every element in Data is an AccountsStruct (since it's populated by the Accounts class's LoadTable method), you could use static_cast for slightly better performance. However, dynamic_cast is always safer—it prevents undefined behavior if someone accidentally adds a different DataStruct subclass to the vector later.

Bonus: Add type-safe helper methods (optional)

To make iteration cleaner, you could add a helper method to the Accounts class that returns a view of the Data vector as AccountsStruct pointers:

class Accounts : public MySQLTable {
public:
    // ... existing LoadTable implementation ...

    std::vector<AccountsStruct*> GetAccounts() {
        std::vector<AccountsStruct*> result;
        for (const auto& ptr : Data) {
            auto* acc = dynamic_cast<AccountsStruct*>(ptr.get());
            if (acc) result.push_back(acc);
        }
        return result;
    }
};

Then you can iterate more simply:

Accounts accountsTable;
accountsTable.LoadTable();
for (auto* account : accountsTable.GetAccounts()) {
    // Use account directly as AccountsStruct*
}

内容的提问来源于stack exchange,提问作者Venelin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 07:47:49