Tất cả các quốc gia có nguồn gốc từ BaseState để biến thành viên mVehicle truy cập các biến lớp ngoài. Tuy nhiên, trong mỗi lớp dẫn xuất, trong tất cả các hàm của mỗi trạng thái, static_cast là cần thiết để truy cập các biến và hàm thành viên lớp dẫn xuất.Biến thành viên lớp dẫn xuất truy cập trong hàm ảo
Bất kỳ giải pháp nào tốt hơn?
- Trong mỗi trạng thái của các lớp dẫn xuất, hãy thêm một con trỏ khác (ví dụ: Convertible * mConvertible). Mỗi trạng thái có con trỏ trùng lặp (mConvertible và mVehicle) trỏ đến cùng một đối tượng. Không nhìn đúng.
- Sử dụng Getter ảo thay vì mVehicle trong lớp cơ sở. Sẽ có quá nhiều cuộc gọi Getter trong lớp cơ sở.
======================== ===========================
Có. Tôi đã thử mẫu như dưới đây, nhưng không thể biên dịch được vì các lỗi như
"car.h: Trong chức năng thành viên 'khoảng trống ảo :: State1 :: run()': car.h: 18: 12: lỗi : 'mVehicle' không được khai báo trong phạm vi này ".
// car.h
#include <iostream>
template <class T>
class Car {
public:
class BaseState {
public:
explicit BaseState(T* vehicle) : mVehicle(vehicle) {}
protected:
T* mVehicle;
};
class State1 : public BaseState {
public:
explicit State1(T* vehicle) : BaseState(vehicle) {}
virtual void run() {
mVehicle->x = 1;
mVehicle->y = 2;
mVehicle->doSomething1();
mVehicle->doSomething2();
processEvent();
}
virtual void processEvent() {
if (mVehicle->val > 2) {
std::cout << "too large" << std::endl;
}
}
};
class State2 : public BaseState {
public:
explicit State2(T* vehicle) : BaseState(vehicle) {}
virtual void run() {
mVehicle->x = 10;
mVehicle->y = 20;
processEvent();
}
virtual void processEvent() {
if (mVehicle->val > 20) {
std::cout << "too large" << std::endl;
}
}
};
virtual void doSomething1() {
val += x * y;
}
virtual void doSomething2() {
val += x + y;
}
protected:
int x;
int y;
int val;
};
// convertible.h
#include "car.h"
#include <iostream>
class Convertible : public Car<Convertible> {
protected:
class State1 : public Car<Convertible>::State1 {
explicit State1(Convertible* vehicle) : Car<Convertible>::State1(vehicle) {}
// want to override functions in base class states
virtual void processEvent() {
if (mVehicle->val > 10) {
std::cout << "too large" << std::endl;
mVehicle->val = 10;
}
}
};
// want to override some base class functions
// and access some special variables
// want to inherit other functions
virtual void doSomething2() {
z = 10;
val += x + y + z;
}
protected:
int z;
};
Nếu tôi sử dụng State1(Car* vehicle)
thay vì State1(T* vehicle)
, có lỗi chuyển đổi bổ sung. Tôi đang làm gì sai?
Nếu chương trình có thể tìm ra rằng Convertible::State1::processEvent()
phải được thực hiện, tại sao nó không thể tự động truyền mVehicle
từ Car*
đến Convertible*
? Rõ ràng là mVehicle
trỏ đến một đối tượng Convertible
khi số Convertible::State1::processEvent()
được suy luận. Chúng tôi không cần mẫu nếu có dàn diễn viên tự động.
Templates. Sử dụng chúng. –
Bạn có thể vui lòng cung cấp thêm thông tin? – dekst
xem câu trả lời. –