Как получить данные члена класса изнутри одного из его класса / структуры члена? - PullRequest
0 голосов
/ 16 июля 2011

Эй, у меня есть абстрактный класс с именем Partition , который является функтором и входит в мой класс ConcavePolygon .Функтор разделения зависит от большого количества данных ConcavePolygon, таких как TPPLPoints и SFMLPoints.

  • Я обнаружил, что, хотя я определил класс внутри класса, от которого он зависит, я не могу легко получить доступ к данным Конкавеса. Как мне это сделать?

  • Я также хочу использовать некоторые функции из класса Body и надеялсясделать это через ConcavePolygon, так как его потомок от него.(нужна функция AddShape ());

вот код, если он полезен:

class ConcavePolygon : public Body{ 
protected:
    std::list<Vector2f> SFMLPoints;
    std::vector <TPPLPoint> TPPLPoints; //TODO: figure out how to make a temp version without Memory Exception

public:
//////////////////// Partitioning/Triangulating Classes /////////////////////////////////////////////////////////////
    class Partition{
    protected:
        virtual void RunAlgorithm(){};

    public:
        Partition(Vector2f* Points, long numbPoints){ //TODO turn this into a base class for triangulate or Convexulate

        //rev up all the needed data structs
        std::list<TPPLPoly> PartitionOutput;
        std::list <TPPLPoly> ::iterator I;

        //Backup the points, and convert them to tppl
        for(int I=0; I<numbPoints; I++){
            TPPLPoints.push_back(TPPLPoint(Points[I].x, Points[I].y));
            SFMLPoints.push_back(Points[I]);}
        TPPLPoly Poly(&TPPLPoints[0], numbPoints, false);

        //clear everything to be filled with the Partition Algorithm
        this->Clear();

        // Run the Partitioning Algorithm
        RunAlgorithm();

        // Convert results to SFML points, shapes, and add to the body
        for( I= PartitionOutput.begin(); I!= PartitionOutput.end();I++){
            sf::Shape TempShape;
            for(int i=0; i< I->GetNumPoints(); i++)
                TempShape.AddPoint( I->GetPoint(i).x, I->GetPoint(i).y);
            this->AddShape(TempShape);
        }
    };
};

    class Convexulate: public Partition{
        bool RunAlgorithm(TPPLPoly& Poly, std::list<TPPLPoly>& PartitionOutput){
            TPPLPartition Partition;
            Partition.ConvexPartition_OPT(&Poly, &PartitionOutput);
        };
    };

    class Triangulate: public Partition{
        bool RunAlgorithm(TPPLPoly& Poly, std::list<TPPLPoly>& PartitionOutput){
            TPPLPartition Partition;
            Partition.Triangulate_OPT(&Poly, &PartitionOutput);
        };
    };
//////////////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////  Constructors    /////////////////////////////////////////////////////
    ConcavePolygon(Vector2f* Points, long numbPoints){
        Convexulate(Points, numbPoints);
    };


};// ConcavePolygon Class

Ответы [ 2 ]

4 голосов
/ 16 июля 2011

В C ++ вложенные классы - это на самом деле просто способ определения пространства имен (и обеспечения защиты: публичный / защищенный / приватный) для имен классов. Они не создают никаких особых отношений между двумя классами, кроме имени: OuterClass :: NestedClass.

Таким образом, вам нужно относиться к вложенным классам, как к отдельным классам. Если вы хотите, чтобы NestedClass получил доступ к закрытым членам OuterClass, вы должны явно объявить его другом OuterClass. Если вы хотите, чтобы NestedClass имел доступ к определенному экземпляру OuterClass, вы должны предоставить ему экземпляр OuterClass.

2 голосов
/ 16 июля 2011

На самом деле эта проблема была решена в отчете о дефектах c ++, и любой текущий (не слишком старый) компилятор c ++ должен уметь это обрабатывать:


В пункте 11.7 [class.access.nest] изменить

Члены вложенного класса не имеют специального доступа ни к членам включающего класса, ни к классам или функциям, которые предоставили дружбу включающему классу; обычные правила доступа (пункт 11 [class.access]) должны соблюдаться. до

Вложенный класс является членом, и поэтому имеет те же права доступа, что и любой другой член.


Вот рабочий пример для вас (скомпилирован нормально с VS2008, но не скомпилируется со старым компилятором, таким как VC6):

class Body{
public:
    void foo()
    {

    }
};
class Outer: public Body {
public:
    class Inner{
    public:
        Inner(Outer& out):m_rOut(out){}
        void foo()
        {
            m_rOut.m_out = 1;   //access private member of Outer class directly
            m_rOut.foo();       //call member function of Body
        }
    private:
        int m_inner;
        Outer& m_rOut;
    };
private:
    int m_out;
};
...