繁体   English   中英

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

[英]Accessing a member of an object void pointer c++

我有一个作业,我必须使用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();
};

我希望能够在void *之后调用PrintToConsole函数。

如果不先铸造void*则无法与它的指针配合使用。 例如,如果它指向“ Star ,则可以执行以下操作:

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

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

您应该将其投放给全班。 但是,如果您确实不想这么做,可以使用offsetof宏:

宏offsetof扩展为类型为std :: size_t的常量,其值是从指定类型的对象的开头到其指定成员的偏移量(以字节为单位),包括填充(如果有)。 如果type不是标准布局类型,则行为未定义。 如果member是静态成员或成员函数,则行为是不确定的。

但是您应该将其投放到班级。

编辑:啊,我看到你想访问该类的方法。 那不可能 您应该将其投放给全班。

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

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

我还建议动态投放可能会更好

由于这是一项作业,因此您最好向老师/导师询问他们在C ++中使用void*类型的意图。 , but there other ways of achieving similar results while maintaining language consistency. 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;
}

这只是一个简单的示例,以说明您的要求,如果您对这个主题感到困惑,最好还是请老师进一步澄清。

希望能对您有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM