1

我在線看到了這個代碼,我想知道它是如何實現的。由於成員函數指針不能分配給基類的成員函數指針,我很好奇派生類的成員函數的指針在哪裏存儲以及如何存儲。繼承成員函數指針

這是測試聲明

#ifndef TestStudent_h 
#define TestStudent_h 

#include <iostream> 
#include <string> 

// Note 1 
#include "TestCase.h" 
#include "TestSuite.h" 
#include "TestCaller.h" 
#include "TestRunner.h" 

#include "Student.h" 

class StudentTestCase : public TestCase { // Note 2 
public: 
    // constructor - Note 3 
    StudentTestCase(std::string name) : TestCase(name) {} 

    // method to test the constructor 
    void testConstructor(); 

    // method to test the assigning and retrieval of grades 
    void testAssignAndRetrieveGrades(); 

    // method to create a suite of tests 
    static Test *suite(); 
}; 
#endif 

頭文件這是添加成員函數某種名單的

// method to create a suite of tests - Note 7 
Test *StudentTestCase::suite() { 
    TestSuite *testSuite = new TestSuite ("StudentTestCase"); 

    // add the tests 
    testSuite->addTest (new TestCaller 
     ("testConstructor", &StudentTestCase::testConstructor)); 
    testSuite->addTest (new TestCaller 
     ("testAssignAndRetrieveGrades", 
     &StudentTestCase::testAssignAndRetrieveGrades)); 
    return testSuite; 
} 

我不知道該功能的實現什麼樣的數據類型成員函數被存儲在,因爲它們不能被存儲在基類已知的任何函數指針類型中。而且它們被存儲的位置將必須知道它們被定義的類的類型,因爲無論哪個實體打電話給他們e對象需要將這些函數與該類型的對象「鏈接」。特別是在這個函數中,TestCaller如何知道如何調用添加到它的成員函數?

+0

@ n.m。但他們需要存儲在某個地方? – Curious

+0

基類不參與,TestSuite是。 – kfsone

+0

對不起,我想我不明白你在問什麼。會員功能不是「存儲」在任何地方,他們只是。成員函數指針存儲在它們的數據類型中。它們是沒有任何結構的原始數據類型。 –

回答

4

我的猜測是,TestCaller有一個構造函數,看起來像

template<class Callee> 
TestCaller(
    const std::string &description, 
    void (Callee::*test_method)()); 

需要注意的是:

  1. 在這個構造函數(即,當它被實例化),該類型的體Callee是已知的。

  2. TestCaller本身必須存儲test_method的方式,並不「知道」 Callee,因爲它不是本身Callee參數化的模板類(事實上,有可能比單一Callee更多)。

所以這是類型擦除的經典案例。有很多這樣的庫(例如,boost::TypeErasureboost::any)。

想法是,TestCaller存儲(可能間接)指向非模板基類的指針。有派生類的模板版本。在這個模板化的ctor中,派生類被實例化,並且這種類型的對象被動態分配。存儲的內容是指向非模板基類的指針。

+0

這太棒了!爲什麼我之前沒有想到這個...... – Curious

+0

@Curious :-)當我第一次看到這種技術時(在一些序列化庫中),我非常高興。 –

+0

但是在代碼中,'new'運算符沒有模板參數被調用。所以這真的會起作用嗎? – Curious