如何从"指向对象的向量中访问对象"在c ++中

时间:2015-02-15 07:10:35

标签: c++ pointers vector

我正在编写一个程序,用于创建指向对象的指针。

如何访问指针从指针到对象矢量引用的单个对象?

我正在尝试在类Object中为向量引用中的指针调用每个对象调用speak()函数。

感谢您的时间

class Object
{
public:
    void speak()
    {
        cout<<"Hello!"<<endl;
    }
};

int main()
{
    int choice;

    vector<Obj*> objVector; //create empty vector of "pointer-to-object"
    Object* ptrObj; //point to object

    while (choice!=5)
    {
        cout <<"1.Create Object\n";
        cout <<"2.Destroy Object\n";
        cout <<"3.Print number of existing Objects\n";
        cout <<"4.Tell existing Objects to say Hello\n";
        cout <<"5.Quit Program"<<endl;
        cout <<"Please enter your choice: ";
        cin >> choice;

    if (choice==5)
        cout <<"\nProgram is quitting\n"<<endl;
    else if (choice==1)
    {
        ptrObj= new Object;
        ObjVector.push_back(ptrObj); //adding an Object object
    }
    else if (choice==2)  //remove object
    {
        objVector.pop_back();
    }
    else if (choice==3)
    {
        cout <<"\nThere are " << objVector.size() <<" objects total.\n" << endl;
    }
    else if (choice==4)
    {
        for (int i=0; i<objVector.size(); i++)
        {
           ????????????
        }
    }
    }
    return 0;
}

4 个答案:

答案 0 :(得分:3)

最简单的方法是使用*(objVector[i])

要发言,objVector[i]->speak只是更短。

答案 1 :(得分:3)

在现有代码中,您可以完全按照在代码中其他位置使用它的方式访问指针:

Object* obj = objVector[i];
obj->speak();
// or, simply:
objVector[i]->speak();

使用运算符->只是说(*objVector[i]).speak()的另一种方式。

或者,编写循环的惯用方法如下所示:

for(vector<Object*>::iterator it = objVector.begin(); it != objVector.end(); ++it) {
    // iterators work like another level of pointers, and need to be dereferenced:
    (*it)->speak();
}

如果您的编译器支持C ++ 11,您可以像这样重写循环:

for(auto it = std::begin(objVector); it != std::end(objVector); ++it) {
    (*it)->speak();
}

或者像这样,使用基于范围的for,为你取消引用迭代器:

for(auto& obj : objVector) {
    obj->speak();
}

顺便说一下,有些情况下你根本不确定objVector[i]是否在向量中,并且访问它可能会使你的程序崩溃甚至导致恶魔从你的鼻腔飞出来。 / p>

为了增加安全性,您可以使用at函数引用向量中的位置,如下所示:

try {
    for (int i=0; i<objVector.size(); i++)
    {
        Object* obj = objVector.at(i);
        obj->speak();
    }
} catch (const std::out_of_range& ex) {
    cerr << "no object at position " << i << " in objVector" << endl;
    cerr << "objVector says " << ex.what() << endl;
}

请注意,虽然它让您有机会在catch块中处理问题,但速度要慢很多。如果try函数抛出异常,catch块将运行循环并停止并运行at块 - 这将是类型out_of_range的例外。另请注意,使用[i]将不会执行相同的操作,因为它不会引发异常 - 它甚至不会检查i是否在向量的长度内。这也恰好是[i].at(i)更快的原因。

最后,还要注意使用迭代器的循环不能遇到这个特定问题,只要你在向量中添加或删除某些内容后不尝试使用迭代器。

答案 2 :(得分:2)

你可以用*取消引用它们。喜欢*(ObjVector [i]) 但是,如果您只需要调用对象的方法,则可以使用 - &gt; ObjVector[i]->speak()

答案 3 :(得分:2)

与此问题无关,但我发表了一些评论来修改该计划。

正如其他人指出的那样,你可以通过执行objVector[i]->speak()从向量中包含的指针调用对象函数。

然而,正如@greyfade指出的那样,内存泄漏问题。当new创建对象时,您必须删除对象。您可以按照delete这样删除对象,

Object* ptr = objVector.back();
objVector.pop_back();
delete ptr;

要清除内存泄漏问题,您可以将Object对象直接存储在objVector而不是Object*中。这样,您就不必担心删除对象。你可以这样做,

int main()
{
    int choice;

    vector<Object> objVector; //create empty vector of "pointer-to-object"

    while (choice!=5)
    {
        cout <<"1.Create Object\n";
        cout <<"2.Destroy Object\n";
        cout <<"3.Print number of existing Objects\n";
        cout <<"4.Tell existing Objects to say Hello\n";
        cout <<"5.Quit Program"<<endl;
        cout <<"Please enter your choice: ";
        cin >> choice;

    if (choice==5)
        cout <<"\nProgram is quitting\n"<<endl;
    else if (choice==1)
    {
        objVector.emplace_back(); //adding an Object object
    }
    else if (choice==2)  //remove object
    {
        objVector.pop_back();
    }
    else if (choice==3)
    {
        cout <<"\nThere are " << objVector.size() <<" objects total.\n" << endl;
    }
    else if (choice==4)
    {
        for (auto& obj : objVector)
        {
          obj.speak();
        }
    }
    }
    return 0;
}

此代码使用的是c ++ 11功能。您可以通过调用emplace_back来添加对象,只需调用pop_back()即可删除对象。这不是很好吗?

还有一件事。你忘记了标题上的一些代码。如果没有这些标题,则无法编译此代码,

#include <iostream>
#include <vector>
using namespace std;

如果此代码可以帮助您,我很高兴。