1

考虑下面的 C++ 代码

class B;

class A{
private:
    B* mB;
};

class B{

private:
    doSomethingImportant();

};

我们有一个包含(具有)对象 B 的对象 A。父对象是 A,子对象是 B。现在,如果我想让 A 让 B 做doSomethingImportant(),我发现将 A 添加为 B 的朋友是唯一的方法去做吧。

friend class A在 B 类内部。这将使 A 的函数能够访问 B 的私有函数。

我觉得这种方法有点奇怪,因为在 Data_Hiding 概念中创建了一个漏洞。有没有更好的方法来建立对象之间的父子关系?还是这是最好的方法?


为这个问题添加我的实际动机

class elevator{
private:
    //The Lift box the elevator controls
    liftboxControlUnit & mLiftBoxCtrlUnit;   

    //constructor
    elevator(int Level=1, int NoOfBanks =1 );

    //Destructor
    ~elevator();

    //Triggers the search to move to the next floor if required 
    void moveLiftToNext();

public:

    //Adds request to the queue
    void addRequest(int FloorNumber){

    //Add the request to the queue. The single button outside the elevator door
    mLiftBoxCtrlUnit.addRequest(FloorNumber);

    }

    //For Emergency. Should be accessible to everyone !
    void setEmergency();
    void unsetEmergency();

};

typedef enum Direction{
    UP,
    DOWN
}direction;

class liftboxControlUnit{
private:

    //The request for various floors
    set<int> mRequestQueue;

    //The various banks for the whole system
    vector<Bank> mBanks;

    //The total number of levels. Remains the same for one building
    const int mTotalLevel;

    //Instruction to move the box to certain level
    void processRequest(){

        //Do the logic to move the box.

    }

    //can passed to the elevator
    void addRequest(int x){
        mRequestQueue.insert(x);
    }

    //Can be set by elevator class
    void setEmergency(){
        //Do the required 
        //Set Emergency on all Banks
    }

    void unsetEmergency(){
        //UnsetEmegency on all banks
    }

    void emergencyListener(){
        //Listen to all the banks if emergency has been set
    }

    void BankFreeListener(){
        //Listen to the banks if any is free

        //If so then
        processRequest();
    }

public:
    //Constructor
    liftboxControlUnit(int TotalLevels, int NoOfBanks): mTotalLevel(TotalLevels){
        for(int i=0 ; i lessthan NoOfBanks; ++ i)
            mBanks.push_back(Bank(0,UP));
    }    
    friend class elevator;
};

class Bank{
private:

    //The dailpad inside the bank
    dailpad & mpad;

    //Current Location
    int mPresentLevel;

    //Current direction of movement
    direction mDirection;

    //Currently moving
    bool mEngaged;

    //Manipulate the bank
    void move(int NoOfMoves){
        setEngaged();

        //Move the elevator

        unsetEngaged();    
    }

    //getters
    int getPresentLevel() const;
    int getDirection() const;

    //setters
    void setPresentLevel(int);
    void setDirection(direction);

    //Manipulate the engaged flag
    bool isEngaged() const;
    bool setEngaged();
    bool unsetEngaged();

    //For emergency
    void reset();

    //Dailpad Listener
    void dailpadListener(){

    }


public:
    Bank(int StartingLevel, direction Direction): mPresentLevel(StartingLevel),
            mDirection(Direction),
            mEngaged(false),
            mpad()
    {

    }

    //For emergency . Should be available for all.
    void SetEmergency();
    void UnsetEmergency();
    bool isEmergency();

    friend class liftboxControlUnit;
};


class dailpad{

private:
    //Some DS to represent the state . probably a 2D Array.

    void renderDisplay();

public:

    //Constructor
    dailpad();

    void getCommand(int x){
        //Depending on the value we can do the following

        //Make necessary changes to the display
        renderDisplay();
    }

    friend class Bank;
};
4

2 回答 2

1

IMO,对于这项任务,您可能应该将“升降箱”类嵌套在控制器类中:

class lift_controller { 

    class lift_box { 
        open_doors();
        close_doors();
        move_to_floor();
    };

    std::vector<lift_box> bank;
};

对于外界来说,根本不需要任何lift_box存在的证据。它只与 进行lift_controller通信,而与 a 的所有外部通信lift_box都通过lift_controller.

在这种情况下(只能lift_controller访问 lift_box ),似乎很清楚(至少对我来说)lift_controller可能需要在 lift_box 上调用的任何操作都应该成为lift_box. 要强制没有其他人可以访问lift_box,请确保 的定义lift_box在 的private:部分中lift_controller

编辑:我应该补充一点,您在上面的问题中编辑的很多设计对我来说几乎没有意义。举个例子,你有银行的方向和当前水平之类的东西。除非我完全误解了你所说的银行的意思,否则这对我来说似乎是一个明显的错误——银行没有处于特定的水平或朝着特定的方向发展。相反,银行中的每个单独的电梯都处于某个水平并且(可能)朝着某个方向移动。

于 2011-11-02T03:54:37.827 回答
0

您似乎希望class A只能访问 B 中的一个私有函数,B::doSomethingImportant()而不能访问其他私有函数。

这通常意味着B::doSomethingImportant()应该真正公开。像这样,A 将无法访问 B 的其他私有数据成员。

此外,如果您不希望其他类访问B::doSomethingImportant(),它们不应该持有指向 B 的指针,而是持有指向 B 的不公开的接口(抽象超类)的指针B::doSomethingImportant()

或者也许其他类只从 B 读取数据。在这种情况下,他们可以持有B const *不允许他们调用的数据B::doSomethingImportant(),除非他们执行const_cast.

于 2011-11-02T03:42:57.830 回答