c++中的父子关系

Parent - Child Relation in C++

本文关键字:父子关系 c++      更新时间:2023-10-16

考虑下面的c++代码

class B;
class A{
private:
    B* mB;
};
class B{
private:
    doSomethingImportant();
};

我们有一个对象a,它包含对象B,父对象是a,子对象是B。现在,如果我想让a让B执行doSomethingImportant(),我认为将a添加为B的朋友是唯一的方法。

类B中的friend class A,这将使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;
};

IMO,对于此任务,您可能应该将"lift box"类嵌套在控制器类中:

class lift_controller { 
    class lift_box { 
        open_doors();
        close_doors();
        move_to_floor();
    };
    std::vector<lift_box> bank;
};

对于外界来说,根本不需要证据证明lift_box存在。它只与lift_controller通信,所有与lift_box的外部通信都要经过lift_controller

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

编辑:我应该补充一点,你在上面的问题中编辑的相当多的设计对我来说几乎没有意义。例如,您拥有诸如银行的方向和当前级别之类的内容。除非我完全误解了你所说的银行,否则在我看来,这是一个明显的错误——银行没有处于特定的水平,也没有朝着特定的方向发展。更确切地说,银行里的每一部电梯都在某个层次上,(可能)朝着某个方向移动。

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

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

进一步,如果你不希望其他类访问B::doSomethingImportant(),它们不应该持有指向B的指针,而应该持有指向不暴露B::doSomethingImportant()的B的接口(抽象超类)的指针。

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