2016-02-12 71 views
0

我有一个任务,我必须使用节点的链接列表与void *作为数据。我将用一个对象填充节点。我想知道一些访问对象成员后,它是否在链接列表中的方式,而不是将其转换为类。可能吗?此外,这是我的代码块,以防万一它有助于澄清我的问题。访问一个对象的成员void pointer C++

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函数。

+0

供参考 - 你不需要一个链表来问这个问题。你想要一个空指针并将其转化为具体的东西。如果不是'Star'类型是一个简单的'int'或'double',答案基本上是一样的。 – PaulMcKenzie

回答

1

如果没有先投射它,则无法使用void*的指针。如果指向在Star,例如,你可以做这样的事情:

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

这就是说,在C++中,这是非常不寻常存储这样的事情。使用模板类会更好,因此您可以获取所需的类型信息。

+0

也许他们还没有研究过模板。 – Barmar

+0

@Barmar几乎可以肯定是这种情况。尽管如此,我仍然认为应该提及它们,这样他们才知道它们存在。 – templatetypedef

+0

谢谢,我不知道是否有更好的方法来做到这一点,而不是套管。 – spartin503

0

你应该将它施放到课堂上。但是,如果你真的不想要,你可以使用offsetof宏:

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

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

编辑:啊,我看你想访问类的方法。这是不可能的。你应该把它投到课堂上。

+0

'offsetof'如何帮助调用对象的PrintToConsole方法? – Barmar

+0

我不明白'offsetof'在这里会有用。你能详细说明一下吗? – templatetypedef

0

不需要。您必须将其转换为适当的对象。

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

我也建议一个动态转换可能会更好

+0

'dynamic_cast' =设计失败,只有极少数例外。 – SergeyA

+0

@SergeyA - 我同意 - 但有了这个问题,这是我能想到的最好的事情。 –

0

因为这是一个任务,你可能是最好问问你的老师/导师,什么他们的意图是在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; 
} 

这仅仅是一个一个简单的例子来说明你在问什么,它仍然是p如果你对这个话题感到困惑,最好可以问你的老师更多的解释。

希望能有所帮助。