【问题标题】:Having the same member function have different definitions for different class instances具有相同的成员函数对不同的类实例有不同的定义
【发布时间】:2018-11-18 03:31:53
【问题描述】:

同一个成员函数是否可以对该类的不同对象有不同的定义?

重要提示:我不能像this solution 那样使用回调。 (原因解释如下示例)

假设我们有这个对象:

struct object
{
    int n;
    int m;
    void f();
};

是否有可能有类似的东西:

object a,b;
// and here to define the functions
a.f() {std::cout << n+m;}
b.f() {std::cout << n-m;}

我不能使用回调的原因是因为我要定义的函数将是递归的并且会溢出。我试图用这种方法做的是创建堆栈的模仿(但所有变量都作为双链表存储在堆上),所以我将调用一个没有局部变量的 void (void) 函数,从而增加函数可以实现的堆栈深度。同样重要的是,我想用这个想法制作一个头文件。为了进一步解释上下文,它应该是这样工作的:

MyHeader.h

template <typename PARAM_TYPE> class HEAP_FUNCTION
{
private:
    struct THIS_CALL // ! THIS HAS NOTHING TO DO WITH THE __thiscall CALLING CONVENTION !
    {
        PARAM_TYPE* PARAM;
        THIS_CALL* next_call;
        THIS_CALL* prev_call;
    };
    THIS_CALL* FIRST_CALL;
    THIS_CALL* CURRENT_CALL;

public:
    HEAP_FUNCTION(PARAM_TYPE* FirstCall)
    {
        FIRST_CALL = new THIS_CALL;
        CURRENT_CALL = FIRST_CALL;
        FIRST_CALL->PARAM = *FirstCall;
    }
    HEAP_FUNCTION(PARAM_TYPE FirstCall)
    {
        FIRST_CALL = new THIS_CALL;
        CURRENT_CALL = FIRST_CALL;
        FIRST_CALL->PARAM = FirstCall;
    }
    ~HEAP_FUNCTION()
    {
        delete FIRST_CALL;
    }
    void call(void);
};

Source.cpp

// This is the ilustration of the recursive method for calculating
//  the 1+2+3+...+n sum.
// The "normal" definition for this function would be:
//
// unsigned long long sum(unsigned long long n)
// {
//     if (n == 0) return 0;
//     return n + sum(n-1);
// }
// 
// The function presented bellow is the equivalent.
struct Param
{
    unsigned long long n;
    unsigned long long return_value;
}
int main()
{
    Param start_value;
    start_value.n = 10; // we will calculate 1+2+...+10
    HEAP_FUNCTION<Param> Gauss(&start_value);

    // We imagine this is where i define call().
    // The code written in this definiton works correctly.
    Gauss.call()
    {
        // Test if the function needs to stop further calls.
        if(CURRENT_CALL->PARAM->n == 0)
        {
            CURRENT_CALL->PARAM->return_value = 0;
            return;
        }

        // Prepare the parameters for the next function call.
        CURRENT_CALL->next_call = new THIS_CALL;
        CURRENT_cALL->next_call->PARAM = new PARAM_TYPE;
        CURRENT_CALL->next_call->prev_call = CURRENT_CALL;
        CURRENT_CALL->next_call->PARAM->n = CURRENT_CALL->PARAM->n - 1;

        // Call the next instance of the function.
        CURRENT_CALL = CURRENT_CALL->next_call;
        call();
        CURRENT_CALL = CURRENT_CALL->prev_call;

        // Collect the return value of the callee.
        CURRENT_CALL->PARAM->return_value = CURRENT_CALL->PARAM->n + CURRENT_CALL->next_call->PARAM->return_value;

        // Delete the space used by the callee.
        delete CURRENT_CALL->next_call;
    }

    // This is the actual call of the function.
    Gauss.call();

    // The return value is found in the start_value struct.
    std::cout << start_value.return_value << std::endl;

    return 0;
}

重要提示:派生整个类将导致 sum(a, b)dif(a, b) 等函数的单个 call() 定义,因为它们将使用相同的 PARAM 结构。 (即使它们不是递归的,并且有人使用它的概率非常小,但是当您的某些函数将具有很多参数并且仅将它们放在堆上会导致更多堆栈时,此方法在较大的程序中是很好的空间)

【问题讨论】:

    标签: c++ function class


    【解决方案1】:

    认为我没有正确理解这个问题,但您是否考虑过函数重载?

    【讨论】:

    • 函数重载不起作用的原因首先是因为用户不应该修改标头,其次因为您不能溢出void (void) 函数,因为编译器不会产生影响。跨度>
    猜你喜欢
    • 1970-01-01
    • 2010-11-21
    • 2013-11-06
    • 1970-01-01
    • 2021-07-18
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多