C ++跨类访问基对象向量中的派生对象的引用

Posted

技术标签:

【中文标题】C ++跨类访问基对象向量中的派生对象的引用【英文标题】:C++ Accessing a reference a derived object in a vector of base object across classes 【发布时间】:2021-12-19 21:59:43 【问题描述】:

我正在尝试创建一个存储基类的向量,然后将其传递给另一个类,该类然后从基类的向量访问派生类我发现了多个涵盖此问题的 Stack Overflow 问题,但它们都缺少某些方面就像跨类传递它或将多个对象存储在一个向量中。 CPP文件

vector<Item*> Items::cM() 
    vector<Item*> M;
    string line;
    string filePath = "...";
    ifstream stream(filePath);
    while (getline(stream, line)) 
        vector <string> IV= UtilFunctions::splitString(line, ',');
        const char *t= IV[0].c_str();
        switch (*t) 
        case 'a': 
            StarterFood tmpStarter = StarterFood(*a,b,c);//Simplified
            Item* b = &tmpStarter;
            M.push_back(b);
            //If I use b here and do b->toString() works as expected
            break;
        
        
        
        
    
    return M;

主要

int main()
    vector <Item*> i= Items::cM();
    items[0]->toString();//This is an overloaded function that all of the derived classes 
    //Throws the error Access violation reading location 0xCCCCCCCC.
    have such as starterfood
    system("pause");
    return 0;

如果需要更多信息,请随时询问。谢谢我也尝试过传递一个指针然后取消引用该指针,但我认为切片我的对象只留下基类,我尝试实现 unique_ptr 但我收到一个语法错误,说没有从 starterFood 返回 unique_ptr 的重载。 错误是访问冲突读取位置 0xCCCCCCCC。

【问题讨论】:

Item* b = &amp;tmpStarter; 您正在存储一个指向临时对象的指针,并在超出范围后尝试访问它。 我确实这么认为,但这是迄今为止唯一不会引发语法错误的尝试,我将如何解决这个问题。我尝试只传递 &tmpStarter 但这只是拉出基类 toString @Passerby 不是指向临时变量的指针,而是指向超出范围的局部变量。指向临时的指针看起来更像&amp;StarterFood(*a,b,c)。不过差别不大,因为最终结果仍然是一个悬空指针。 一些相关的阅读材料(我不确定哪个是适合这个副本的):Appending vector of pointers inside member function of a class causing odd behaviour -- printf() seems to change a variable -- What is difference between instantiating an object using new vs. without 使用unique_ptr 可能是个好主意。我建议修改您的问题以显示该方法并询问您以这种方式遇到的(第一个)错误。 【参考方案1】:

按照建议,我使用了 unique_ptr,我必须在派生类上使用 make_unique,并在存储在向量中时移入派生类,并将所有 vector 替换为 vector 但它现在可以工作了。

vector<unique_ptr<Item>> Items::cM() 
    vector<unique_ptr<Item>> M;
    string line;
    string filePath = "...";
    ifstream stream(filePath);
    while (getline(stream, line)) 
        vector <string> IV= UtilFunctions::splitString(line, ',');
        const char *t= IV[0].c_str();
        switch (*t) 
        case 'a': 
            unique_ptr<StarterFood> tmpStarter = make_unique<StarterFood> 
            (*a,b,c);
            M.push_back(std::move(tmpStarter));
            break;
        
        
        
        
    
    return M;

然后在main中

    vector<unique_ptr<Item>> i= Items::cM();
    items[0]->toString();//This is an overloaded function that all of the 
    derived classes
    system("pause");
    return 0;

这解决了我最初尝试的对象切片问题。

【讨论】:

以上是关于C ++跨类访问基对象向量中的派生对象的引用的主要内容,如果未能解决你的问题,请参考以下文章

c#如何跨线程调用窗体控件

Java修饰符号类型

访问修饰符和继承

访问修饰符 程序集 静态方法

Java访问权限修饰符

跨线程操作Treeview