访问对象 void 指针 c++ 的成员

Accessing a member of an object void pointer c++

本文关键字:成员 c++ 指针 对象 void 访问      更新时间:2023-10-16

我有一个任务,我必须使用以void*作为数据的节点链表。我会用一个对象填充节点。我想知道在对象进入链表后访问对象成员的某种方法,而不是将其强制转换为类。可能吗?另外,这是我的代码块,以防万一它有助于澄清我的问题。

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*的尖头,就无法使用它。如果它指向一个 Star ,例如,您可以执行以下操作:

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

也就是说,在C++中,存储这样的东西是非常不寻常的。最好使用模板类,以便获取所需的类型信息。

No.您必须将其强制转换为适当的对象。

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

我还建议动态演员阵容可能会更好

你应该把它投射到类中。但是如果你真的不想,你可以使用 offset 宏:

宏偏移量扩展到 std::size_t 类型的常量, 其值是从 指定类型的对象为其指定成员,包括填充 if 任何。 如果类型不是标准布局类型,则行为未定义。 如果成员是静态成员或成员函数,则行为为 定义。

但是你应该把它投到课堂上。

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

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

直接回答:

我想知道在对象进入链表后访问对象成员的某种方法,而不是将其强制转换为类。可能吗?

是的,这是可能的,但不要使用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;
}

这只是一个简单的例子来说明你在问什么,如果你对这个话题感到困惑,最好还是向你的老师询问更多的澄清。

希望能有所帮助。