«Идиома именованного конструктора», кажется, противоречит правилу, согласно которому статический метод не может получить доступ к нестатической функции-члену. Любое объяснение? - PullRequest
2 голосов
/ 06 января 2012

Согласно этому сайту статические методы

static Point rectangular(float x, float y);    
static Point polar(float radius, float angle);

вызывают приватный конструктор Point (нестатический метод), как показано ниже:

#include <cmath>               // To get std::sin() and std::cos()

class Point {
 public:
   static Point rectangular(float x, float y);      // Rectangular coord's
   static Point polar(float radius, float angle);   // Polar coordinates
   // These static methods are the so-called "named constructors"
   ...
 private:
   Point(float x, float y);     // Rectangular coordinates
   float x_, y_;
 };

 inline Point::Point(float x, float y)
   : x_(x), y_(y) { }

 inline Point Point::rectangular(float x, float y)
 { return Point(x, y); }

 inline Point Point::polar(float radius, float angle)
 { return Point(radius*std::cos(angle), radius*std::sin(angle)); }
};

Редактировать: Мне сложно принять ответ, поскольку я не знаю, какой из них правильный.

Ответы [ 6 ]

4 голосов
/ 06 января 2012

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

Конструкторы - это специальные функции-члены, которые не имеют имени и не могут быть вызваны пользователем.Они могут быть вызваны неявно только как часть языка, а именно, либо через инициализацию статического или автоматического объекта, либо через выражение new.Вы не можете взять адрес конструктора, и конструктор не может быть const - или иным образом квалифицированным.

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

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

1 голос
/ 06 января 2012

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

1 голос
/ 06 января 2012

Причина «правила», которое вы цитируете (на самом деле это не так), заключается в том, что функция-член static не имеет неявного экземпляра, с которым она работает, то есть нет this.

Тем не менее, static функция-член может вызвать функцию-не-1008 *, если у нее есть экземпляр, с которым она может вызвать функцию-член. В этом случае он создает свой собственный экземпляр, вызывая закрытый конструктор.

Сравнить (тривиальный пример, я признаю)

class Greeter {
    std::string who;

  public:
    Greeter(std::string const &name) : who(name) { }

    static void greet(Greeter const &gr) { gr.hello(); }

  private:
    void hello() { std::cout << "Hello, " << who << "!\n"; }
 };

Здесь static член greet используется для вызова private метода hello. Это может быть сделано, поскольку ему передается явный экземпляр Greeter. (Это не будет работать с автономной функцией, если не объявлено friend.)

1 голос
/ 06 января 2012

Конструктор - это особый случай, потому что конструктор не нуждается в существующем объекте для вызова.

Правило, которое вы упомянули, было бы лучше запомнить как "Aстатическая функция-член не имеет неявного this указателя ".

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

«Идиома Именованного Конструктора», кажется, противоречит правилу, согласно которому Статический метод не может получить доступ к нестатической функции-члену. любой Объяснение

Причина, по которой вы цитируете правило «статическая функция-член не может получить доступ к нестатической функции-члену», заключается в том, что статическая функция-член не имеет указателя this. И нужна эта функция для всех нормальных нестатических функций-членов.

Но конструктор - это специальная функция-член, к которой применено много специальных правил:

например, из стандарта С ++ 3290 12.1 Конструктор не должен быть виртуальным (10.3) или статическим (9.4).

И вы уже должны знать, что вы можете вызывать конструктор без экземпляра этого класса, без указателя this. Вот почему вы можете создать экземпляр класса в статической функции-члене или в любом другом месте в глобальной области видимости (если оно имеет определение):

Point(x, y);

Так это объясняет ваш вопрос?

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

rect () и polar () возвращают безымянные объекты Point, вызывая конструктор напрямую.Причина, по которой вы не можете нормально вызывать методы экземпляра из статического метода, заключается в том, что экземпляр еще не существует.Когда конструктор вызывается напрямую, он создает безымянный экземпляр перед выполнением тела конструктора.

...