2016-01-05 4 views
0

Это факт, что вы можете явно обращаться к переменным-членам (внутри функции-члена, а не к определенному конструктору), используя этот синтаксис: this->member_name (т. Е. Чтобы отличить аргумент функции от то же имя).Использование оператора области доступа для доступа к переменным нестатического элемента

Кроме того, я думал, что синтаксис ClassName::static_member зарезервирован для доступа к статическим членам вне класса.

Тогда я был удивлен, когда я понял, что следующий set_2() метод работает, как можно было ожидать:

#include <iostream> 

struct A { 
    int x; 
    // The two following methods seem to act similarly: 
    void set_1(int x) { this->x = x; } 
    void set_2(int x) { A::x = x; } 
}; 

int main() 
{ 
    A a; 

    a.set_1(13); 
    std::cout << a.x << std::endl; 

    a.set_2(17); 
    std::cout << a.x << std::endl; 

    return 0; 
} 

Является ли это хорошо и действует практика использовать оператор области видимости (A::x) в этом случае? Я бы предпочел это, вместо использования синтаксиса this->x.

+2

IMHO, не используйте имена, вызывающие подобные конфликты, и вам не нужно использовать какой-либо синтаксис. –

+0

@JoachimPileborg: многие люди дают этот совет, но я считаю более ясным, чтобы моя часть давала одно и то же имя, особенно с прямым назначением (только одно имя для одной задачи). – yolenoyer

+1

Я бы украсил одно из имен. Мне очень нравится trailing _ в качестве элемента-декоратора. В качестве альтернативы вы можете использовать префикс «m_» для члена и/или «a_» для аргумента. Важно выбрать один стиль и придерживаться его. –

ответ

2

Использование A::x в этом случае справедливо, но я думаю, что this->x более идиоматических и менее подвержен ошибкам (читатель кода может сразу увидеть, что x является членом класса, не задумываясь, что такое A).

0

A::x, в вашем случае, по-прежнему относится к вашей обычной переменной-члену; он просто явно указывает , которыйx вы имеете в виду. Рассмотрим класс, производный от двух других классов, которые имеют элемент с таким же именем (не то, что это очень хороший стиль кодирования):

struct A { int x; }; 
struct B { int x; }; 
struct C : A, B 
{ 
    int foo() const 
    { 
    // return x; // ambiguous: which x do you mean? 
    return A::x; // unambiguous 
    } 
}; 
2

В соответствии со стандартом C++ (Область применения 3.3.7 Класс)

2 Наименование члена класса должны использоваться только следующим образом:

- в рамках своего класса (как описано выше) или класс, полученный (статья 10), из его класса,

- после. Оператор применяется к выражению типа его класса (5.2.5) или класса, производного от этого класса,

- после того, как оператор -> применяется к указателю на объект своего класса (5.2.5) или класс, полученный из его класса,

- после действия оператора (5.1) разрешения области видимости, применяемого к имени его класса или класса, производного от его класса.

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

struct Base 
{ 
    virtual ~Base() {}; 
    virtual void Hello() const { std::cout << "Base" << std::endl; } 
}; 


struct Derived : Base 
{ 
    virtual void Hello() const 
    { 
     Base::Hello(); 
     std::cout << "and Derived" << std::endl; 
    } 
}; 

Derived d; 

d.Hello(); 
Смежные вопросы