Есть ли какое-либо применение для класса, чтобы он содержал только (по умолчанию) закрытые члены в c ++?

Члены класса по умолчанию являются закрытыми в c ++.

Следовательно, мне интересно, есть ли какое-либо возможное использование для создания класса, в котором все его члены (переменные и функции) по умолчанию установлены в private.

Другими словами, существует ли какое-либо значимое определение класса без каких-либо ключевых слов? public, protected или же private?

25

Решение

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

Только друг ключевого класса имеет доступ к protectedMethod():

// All members set by default to private
class PassKey { friend class Foo; PassKey() {} };

class Bar
{
public:
void protectedMethod(PassKey);
};

class Foo
{
void do_stuff(Bar& b)
{
b.protectedMethod(PassKey());  // works, Foo is friend of PassKey
}
};

class Baz
{
void do_stuff(Bar& b)
{
b.protectedMethod(PassKey()); // error, PassKey() is private
}
};
25

Другие решения

Диспетчерская метка. Он используется в стандартной библиотеке для Теги категории итератора, чтобы выбрать алгоритмы, которые могут быть более эффективными с определенными категориями итераторов. Например, std::distance может быть реализовано что-то вроде этого: (на самом деле это реализовано почти так же, как в gnu libstdc ++, но я немного изменил его, чтобы улучшить читаемость)

template<typename Iterator>
typename iterator_traits<Iterator>::difference_type
distance(Iterator first, Iterator last)
{
return __distance(first, last,
typename iterator_traits<Iterator>::iterator_category());
}

куда __distance это функция, которая перегружена, чтобы вести себя более эффективно для std::random_access_iterator_tag (которая является пустой структурой, но может быть просто классом), просто используя last - first вместо поведения по умолчанию подсчета, сколько приращений требуется, чтобы получить first в last,

18

Приобретение широкого применения ресурсов?

#include <iostream>

class C {
C() {
std::cout << "Acquire resource" << std::endl;
}~C() {
std::cout << "Release resource" << std::endl;
}

static C c;
};C C::c;

int main() {
return 0;
}

Как указано в комментариях ниже, я имею в виду промышленное приложение, которое должно было «блокировать» некоторые устройства во время работы программы. Но, возможно, можно найти другое применение для этого, поскольку, в конце концов, это всего лишь «вырожденный» случай или RAII.


Что касается использования «приватных» методов вне блока объявления: здесь я использую статический член. Так что, это объявленный в точке, где частные члены доступной. Вы не ограничены конструктором / деструктором. Вы можете даже (ab) использовать статические методы, а затем вызывать private пример методы с использованием свободный интерфейс:

class C {
C() { std::cout << "Ctor " << this << std::endl; }
~C() { std::cout << "Dtor" << this << std::endl; }

static C* init(const char* mode) {
static C theC;

std::cout << "Init " << mode << std::endl;
return &theC;
}

C* doThis() {
std::cout << "doThis " << std::endl;

return this;
}

C* doThat() {
std::cout << "doThat " << std::endl;

return this;
}

static C *c;
};C *C::c = C::init("XYZ")
->doThis()
->doThat();

int main() {
std::cout << "Running " << std::endl;
return 0;
}

Этот код остается в силе (как и все C члены доступны в точке декларация из C::c). И будет производить что-то подобное:

Ctor 0x601430
Init XYZ
doThis
doThat
Running
Dtor0x601430
15

Значимое? Хорошая практика? Вероятно, нет, но здесь идет:

class DataContainer {
friend class DataUser;
int someDataYouShouldNotWorryAbout;
};

class DataUser {
public:
DataUser() {
container.someDataYouShouldNotWorryAbout = 42;
}
private:
DataContainer container;
};
7

Нет, нет смысла создавать класс без открытых переменных-членов и / или функций, так как не было бы способа получить доступ к чему-либо в классе. Даже если явно не указано, наследство также является частным.

Конечно, вы могли бы использовать friend как предложено, но это создаст ненужную свертку.


С другой стороны, если вы используете struct и не class чтобы определить класс, тогда вы получите все публично. Это может иметь смысл.

Например :

struct MyHwMap {
unsigned int field1 : 16;
unsigned int field2 : 8;
unsigned int fieldA : 24;
};
1

По общему признанию, уродливый случай много, много лет назад и не в C ++, но идея все еще применима:

В библиотеке времени выполнения произошла ошибка. На самом деле исправление некорректного кода вызовет другие проблемы, поэтому я написал процедуру, которая нашла поврежденный фрагмент кода и заменила его верной версией. У оригинального воплощения не было никакого интерфейса вообще кроме его создания.

0
По вопросам рекламы [email protected]