C ++从地址

时间:2016-02-16 16:18:40

标签: c++ inheritance vector stl polymorphism

我想知道在C ++中是否有办法知道地址是什么数据结构。例如,我有一个基类(A),它有两个继承的类(B和C)。在第四类(D)中,我有两个STL向量,一个包含B的指针,第二个包含C的指针。

在D中,我正在实现一个撤销对象A的方法。在该方法中,我正在使用D的另一个实现函数,如果对象A在那里,则在向量中搜索并返回指向该对象的指针。

之后是否有办法操纵对象A的适当向量,直接将其从向量中删除(知道它是什么向量及其在向量中的位置)?

A* D::findA(string word)
{
    for (unsigned int i = 0; i < vectorOfB_.size(); i++) {
        if ( vectorOfB_[i]->getWord() == word)
            return vectorOfB_[i];
    }

    for (unsigned int i = 0; i < vectorOfC_.size(); i++) {
        if (vectorOfC_[i]->getWord() == word)
            return vectorOfC_[i];
}

bool D::withdrawA(string word)
{
    A* obj = findA(word);
    if (obj != nullptr) {
    }
    return false;
}

此时,我知道该方法找到了对象A,我知道它的地址,但我不知道它是什么向量。我想使用STL向量类的擦除()方法将其从向量中撤回,但不再进行循环以检查向量。

3 个答案:

答案 0 :(得分:1)

我猜你可以使用dynamic_cast来确定A的指针是B型还是C型。

bool D::withdrawA(string word)
{
    A* obj = findA(word);
    if (obj != nullptr) {
        if(dynamic_cast<B*>(obj) != nullptr) {
           // do something here for the B vector
        }
        else if(dynamic_cast<C*>(obj) != nullptr)
        {
           // do something here for the C vector
        }
    }
    return false;
}

答案 1 :(得分:1)

由于您正在查询类的成员(word)以识别对象,因此我认为您不需要一些魔法机制来实现您想要的内容。

您可以使用STL算法,例如具有以下类:

#include <memory>
#include <algorithm>
#include <vector>
#include <string>


using namespace std;


class A {
public:
    A(string word = "") :m_word(word){}
    virtual inline string getWord() { return m_word; }
protected:
    string m_word;
};

class B : public A { 
public: 
    B(string word = "") : A(word) {} 
};  

class C : public A { 
public:
    C(string word = "") : A(word) {} 
};


typedef shared_ptr<A> a_ptr;      
typedef vector<a_ptr> a_vector;

你可以写一个函数:

a_ptr find_A(a_vector v, string word, bool erase = false){

    // Find the element.
    auto it = find_if(v.cbegin(), v.cend(),
        [word](const a_ptr &elem) {
            return elem->getWord() == word;
        }
    );

    // If you want to erase and it was found.
    // The code below can be implemented in a more elegant way, but
    // for that your classes will require you overload < operator and == operator.
    if (erase && it != v.end()) {
        v.erase(remove_if(v.begin(), v.end(), 
            [word](a_ptr elem){
                return elem->getWord() == word;
            }
        ), v.end());
    }

    return *it
}

现在你可以使用两个向量的函数。

更具体的例子。

您也可以使用STL算法从矢量中删除:

假设您找到了一些A*

A* a_ptr =  findA(word);

然后你可以使用STL erase,remove_if idiom:

vectorOfB_.erase(remove_if(vectorOfB_.begin(), vectorOfB_.end(), 
    [a_ptr](A* elem){
        return elem->getWord() == a_ptr->getWord();
    }
), vectorOfB_.end());

vectorOfC_.erase(remove_if(vectorOfC_.begin(), vectorOfC_.end(), 
    [a_ptr](A* elem){
        return elem->getWord() == a_ptr->getWord();
    }
), vectorOfC_.end());

答案 2 :(得分:0)

在C ++中,无法通过地址直接了解数据结构。