2016-06-16 15 views
5

Cần có một biến chức năng bên trong lớp có chức năng mặc định và chức năng của nó có thể được ghi đè. Ví dụ về cách tôi thích/muốn làm (không may là không thành công):C++ class std :: chức năng có chức năng mặc định và có thể thay đổi

#include <iostream> 
#include <functional> 
using namespace std; 

class Base 
{ 
    public: 

    std::function<bool(void)> myFunc(){ 
    cout << "by default message this out and return true" << endl; 
    return true;} 
}; 

bool myAnotherFunc() 
{ 
cout << "Another functionality and returning false" << endl; 
return false; 
} 

int main() 
{ 
    Base b1; 
    b1.myFunc(); // Calls myFunc() with default functionality 
    Base b2; 
    b2.myFunc = myAnotherFunc; 
    b2.myFunc(); // Calls myFunc() with myAnotherFunc functionality 
    return 0; 
} 

Tôi biết, mã này không biên dịch. Bất kỳ ai có thể giúp khắc phục điều này hoặc đề xuất điều gì đó. Không cần phải là std :: function, nếu có một cách khác để thực hiện logic này. Có lẽ nên sử dụng lambda ?!

Trả lời

5

Thay đổi:

class Base { 
    public: 
    std::function<bool()> myFunc = [](){ 
    cout << "by default message this out and return true" << endl; 
    return true; 
    }; 
}; 

Live Demo

+0

Lưu ý rằng điều này gần như không thể tránh khỏi kết quả trong hành vi undefined một lần 'Base' được đặt trong một tệp tiêu đề, vì '[]() {}' được sử dụng trong mỗi compi trình xây dựng tổng hợp của đơn vị lation và có một loại id khác trong các đơn vị biên dịch khác nhau. Điều này vi phạm ODR cho nhà xây dựng. Để sửa lỗi này, hãy khai báo 'Base();' trong phần đầu, và 'Base :: Base() = mặc định;' (hoặc bất kỳ thứ gì) trong * chính xác một tệp * cpp. Khi nó xảy ra, hầu hết các trình biên dịch không làm những điều khủng khiếp trong trường hợp này của hành vi không xác định * tại thời điểm này *, vì vậy nó sẽ vượt qua không được chú ý. – Yakk

+0

Tạo! có một vấn đề khác. Xem mã: https://ideone.com/pO7oRZ lớp dẫn xuất s.play() sẽ gọi Base :: myFunc(), đó là dễ hiểu, bởi vì myFunc() không phải là ảo; Có cách nào để làm theo cách này mà vở kịch này() không gọi Base :: myFunc(). Sẽ gọi con trai :: myFunc() – Samps

+0

@ user2440139 Hãy xem [demo] (http://coliru.stacked-crooked.com/a/29f789bd4273558a). – 101010

1

Giải pháp với những thay đổi tối thiểu:

http://coliru.stacked-crooked.com/a/dbf33b4d7077e52b

class Base 
{ 
    public: 
    Base() : myFunc(std::bind(&Base::defAnotherFunc, this)){} 

    std::function<bool(void)> myFunc; 

    bool defAnotherFunc(){ 
    cout << "by default message this out and return true" << endl; 
    return true;} 
}; 
Các vấn đề liên quan