访问对象void pointer c++的成员

Accessing a member of an object void pointer c++

我有一个作业,我必须使用节点的链表并将 void* 作为数据。我会用一个对象填充节点。我想知道在链接列表中访问对象成员的一些方法,而不是将其强制转换为 class。可能吗?此外,这是我的一段代码,以防它有助于澄清我的问题。

struct Node
{
    void* data_;
    Node* next_;

    Node()
    {
        data_ = 0;
        next_ = 0;
    }
};

class Star
{
private:
    char name_[ENTRY_SZ];
    long temperature_;
    double luminosity_;
    double mass_;
    double radius_;

public:
    static char filePath_[ENTRY_SZ];

    Star(char* name);
    void SetTemperature(char* temp);
    void SetLuminosity(char* lum);
    void SetMass(char* mass);
    void SetRadius(char* rad);
    void PrintToConsole();
    void AppendToFile();
};

我希望能够在 PrintToConsole 函数处于 void* 后调用它。

如果不先施放 void* 的指针,则无法使用它。例如,如果它指向 Star,您可以这样做:

static_cast<Star*>(data_)->PrintToConsole(); // Haha, Star star!

就是说,在 C++ 中,存储这样的东西是很不寻常的。你最好使用模板 class 这样你就可以得到你需要的类型信息。

您应该将其转换为 class。但是如果你真的不想,你可以使用offsetof宏:

The macro offsetof expands to a constant of type std::size_t, the value of which is the offset, in bytes, from the beginning of an object of specified type to its specified member, including padding if any. If type is not a standard layout type, the behavior is undefined. If member is a static member or a member function, the behavior is undefined.

但您应该将其转换为 class。

编辑:啊,我看到你想访问 class 的方法。那是不可能的。您应该将其投射到 class.

没有。您必须将其转换为适当的对象。

我会质疑使用 void 指针的原因。

我还建议动态转换可能更好

由于这是一项作业,您最好询问您的 teacher/mentor 他们在 C++ 中使用 void* 类型的意图是什么; void* 类型本身并不是 不好的 ,但是还有其他方法可以在保持语言一致性的同时实现类似的结果。

直接回答:

I want to know some way of accessing the members of the object after it is in the linked list, other than casting it to the class. Is it possible?

是的,这是可能的,但不能使用 void* 习语。以您的代码为例,如果您保留 void*,您确实必须转换为适当的类型并且 某些 指向的类型兼容,例如:

struct Node
{
    void* data_;
    Node* next_;

    Node()
    {
        data_ = 0;
        next_ = 0;
    }
};

class Star
{
    public:
        void PrintToConsole() {} // empty to avoid not-defined errors
};

int main() {
    Node n;
    n.data_ = new int(42);
    static_cast<Star*>(n.data_)->PrintToConsole(); // this will compile fine, but what happens here is undefined
    delete static_cast<int*>(n.data_); // can't delete void*, have to cast
    return 0;
}

同样,由于这是一项作业,您的教授可能只是在尝试教授指针和类型转换或类型系统,而您可能还没有了解 C++ 模板,但既然您提出了问题,这是您使用模板的代码:

template < typename T >
struct Node
{
    T data_;
    Node* next_;

    // use member init list to construct default T object
    Node() : data_(), next_(0)
    {
    }
};

class Star
{
    public:
        void PrintToConsole() {} // empty to avoid not-defined errors
};

int main() {
    Node<Star*> n;
    n.data_ = new Star();
    n.data_->PrintToConsole(); // OK
    delete n.data_; // no cast needed since data_ is a Star* type

    Node<int*> n2;
    n2.data_ = new Star(); // compiler error (data_ is of type int* not Star*)
    n2.data_->PrintToConsole(); // compiler error (int has no member named PrintToConsole)
    delete n.data_;
    return 0;
}

这只是一个简单的例子来说明你的问题,如果你对这个话题感到困惑,最好还是向你的老师寻求更多的解释。

希望能帮到你。