Как я могу определить поля / методы класса в меньшем пространстве в C ++ - PullRequest
0 голосов
/ 31 января 2012

Это мой заголовок:

#ifndef MYCLASSES_H_
#define MYCLASSES_H_

#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))

namespace mynamespace {

class A
{
    class B
    {
        class C
        {
            void doStuff(B *pB);
        }

        static const C SOME_ARRAY[];
        static const int SOME_ARRAY_COUNT;
    }
}

} //namespace mynamespace
#endif /* MYCLASSES_H_ */

И это CPP:

#include "myclasses.h"

namespace mynamespace {

void A::B::C::doStuff(A::B *pB)
{
    /* ... */
}

const A::B::C A::B::SOME_ARRAY[] = {
    /*...*/
};

const A::B::SOME_ARRAY_COUNT = ARRAY_SIZE(

} //namespace mynamespace

Что мне сделать, чтобы определения в файле .CPP имели более короткие имена? Это невероятно громоздко.

Ответы [ 7 ]

3 голосов
/ 31 января 2012

Человек идет к врачу. Он говорит: «Доктор, у меня болит голова, когда я бью ее об стену». Доктор говорит: «Не бей головой о стену, и голова перестанет болеть».

Поскольку B и C находятся в частной секции класса А., мир их не видит.

Так что нет необходимости вкладывать их внутрь А, просто сделайте их невидимыми для внешнего мира.
Самый простой способ сделать это - поместить их в анонимное пространство имен внутри исходного файла.

#ifndef MYCLASSES_H_
#define MYCLASSES_H_

#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))

namespace mynamespace {

class A
{
}

} //namespace mynamespace
#endif /* MYCLASSES_H_ */

И это CPP:

#include "myclasses.h"


namespace
{
    // This is an anonymouse namespace
    // It does not export it symbols outside the compilation unit.
    // So only A should be able to see them
    class B
    {
            static const C SOME_ARRAY[];
            static const int SOME_ARRAY_COUNT;
    };
    class C
    {
            void doStuff(B *pB);
    };
}
void C::doStuff(B *pB)
{
    /* ... */
}

const C B::SOME_ARRAY[] = {
    /*...*/
};

const B::SOME_ARRAY_COUNT = ARRAY_SIZE(
2 голосов
/ 31 января 2012

typedefs позволяют сократить наименование:

#include "MYCLASSES.h"

namespace mynamespace {

typedef A::B b;
typedef b::C c;

void c::doStuff(b *pB)
{
    /* ... */
}

const c b::SOME_ARRAY[100] = {
    /*...*/
};

const int b::SOME_ARRAY_COUNT = ARRAY_SIZE(SOME_ARRAY);

} //namespace mynamespace
2 голосов
/ 31 января 2012

Может быть попытаться использовать объявление об использовании:

using A::B;
0 голосов
/ 31 января 2012

Кроме того, вы можете написать реализации в заголовочных файлах.Это очень плохая практика.

0 голосов
/ 31 января 2012

Нет никакого реального способа сделать это, кроме как что-то вроде:

    #define AB mynamespace::A::B;

Чтобы разрешить это:

    mynamespace::A::B::C myobj;

Обратите внимание, что многие программисты (включая меня) думают, что этоплохая практика, потому что не очевидно, что такое AB.

Стать:

    AB::C myobj;

Вы не можете использовать 'using' для классов, только пространства имен.Таким образом, в файле cpp вы можете сделать:

    using mynamespace;
    A::B::C myobj;

Но не:

    using mynamespace::A::B;
    C myobj;

Как правило, многие люди согласны с тем, что наилучшей практикой является полное определение имен.

0 голосов
/ 31 января 2012

Нет чистого способа сделать это. Если бы это были вложенные пространства имен, вы могли бы использовать using или namespace aliasing.

Так как это уроки, лучшее, что я могу придумать, это:

#define B A::B
#define C B::C

но это определенно не чисто. Я бы не стал это делать.

0 голосов
/ 31 января 2012

К сожалению, вы не можете. Это всего лишь синтаксическое свойство C ++.

Как следствие, вы должны предпочесть плоские иерархии вложений в C ++: не вкладывать классы бесконечно, помещать их в одно и то же пространство имен верхнего уровня. На других языках это просто нет-нет, так как в нем просачиваются детали реализации в общедоступный интерфейс. 1

Не так в C ++, так как здесь у вас есть отдельные блоки компиляции, чтобы обеспечить инкапсуляцию и сокрытие информации. Так что плоские иерархии на самом деле хороши по большей части.


1 Но даже в других языках три вложенных класса проталкивают конверт.

...