Ответ 1
Я думаю, что я бы предпочел "A:: DoStuff()", так как более ясно, что вызывается статический метод.
Скажем, у меня есть:
class A {
public:
static void DoStuff();
// ... more methods here ...
};
И позже у меня есть функция, которая хочет вызвать DoStuff:
B::SomeFunction(A* a_ptr) {
Лучше сказать:
a_ptr->DoStuff();
}
Или это лучше, даже если у меня есть указатель на экземпляр:
A::DoStuff()
}
Это только вопрос стиля, но я хотел бы получить некоторые обоснованные мнения, прежде чем принимать решение.
Я думаю, что я бы предпочел "A:: DoStuff()", так как более ясно, что вызывается статический метод.
Лучше вызвать статический метод по имени, а не через объект, поскольку он фактически не использует этот объект вообще. В Java такая же проблема существует. Не слишком необычная проблема в Java заключается в следующем:
Thread t = getSomeOtherThread();
t.sleep(1000);
Это компилируется отлично, но почти всегда является ошибкой. Thread.sleep()
- статический метод, который заставляет текущий поток спать, а не тот поток, который действует, поскольку код, кажется, подразумевает.
Я лично предпочитаю соглашение A:: DoStuff(), потому что он сразу же очищает всех, кто читает код, который вызывает вызов статической функции-члена.
Хотя я согласен, что A:: DoStuff() яснее, и это то, что я бы написал сам, я могу увидеть аргумент для перехода через указатель, который "предположим, что имя класса изменяется". Если класс A становится классом B, нам нужно только обновить имя класса в одном месте (объявление указателя) вместо двух.
Просто мысль...
Джон Скит открыл мне глаза, почему вы не должны вызывать статический метод с помощью указателя экземпляра. Его пример представлен на Java, но концепция также относится к С++:
Thread t = new Thread(...);
t.start();
t.sleep(1000); // Which thread does it look like this will affect?
Как я прокомментировал, когда я впервые прочитал его ответ: "Пока я не прочитал [Jon post], я подумал о возможности вызова статических методов с помощью ссылки на экземпляр объекта. Теперь я знаю лучше".
Короче говоря, вызовите статические методы, используя имя класса, а не экземпляр. По-моему, это больше, чем проблема стиля - это может привести к ошибочному, ошибочному коду.
Как правило, я делаю A:: DoStuff(); вместо a- > DoStuff(); потому что, может быть, когда-нибудь у функции, в которой я работаю, больше не будет указателя этого экземпляра из-за рефакторинга. Но это общая вещь стиля, в которой вы не должны потерять сон.
Я видел много вопросов на Java, если люди называли статический метод, используя синтаксис вызова метода экземпляра через объект, а объект на самом деле является подклассом типа переменной, люди задаются вопросом, почему он не вызывает статический метод с тем же именем в подклассе. Тот факт, что они вызывают его через объект, заставляет их думать, что это метод экземпляра, который можно переопределить, и он каким-то образом выполняет динамический поиск в режиме исполнения с использованием типа объекта.
Но, конечно, объект никогда не используется в вызове вообще - только тип переменной используется во время компиляции, чтобы решить, какой он статический метод класса. Поэтому, если вы помещаете туда объект, он полностью вводит в заблуждение, потому что он заставляет людей думать, что он используется, когда это не так. Вот почему я предпочитаю только вызов статических методов через имя класса - он в точности эквивалентен вызову его через переменную типа класса; но он точно говорит о том, что происходит, без лишней вводящей в заблуждение дополнительной информации.