Accesses a member of its operand. Show
Contents
[edit] ExplanationBuilt-in subscript operator provides access to an object pointed-to by the pointer or array operand. Built-in indirection operator provides access to an object or function pointed-to by the pointer operand. Built-in address-of operator creates a pointer pointing to the object or function operand. Member of object and pointer to member of object operators provide access to a data member or member function of the object operand. Built-in member of pointer and pointer to member of pointer operators provide access to a data member or member function of the class pointed-to by the pointer operand. [edit] Built-in subscript operatorThe subscript operator expressions have the form
1) For the built-in operator, one of the expressions (either expr1 or expr2) must be a glvalue of type “array of T” or a prvalue of type “pointer to T”, while the other expression (expr2 or expr1, respectively) must be a prvalue of unscoped enumeration or integral type. The result of this expression has the type 2) The form with brace-enclosed list inside the square brackets is only used to call an overloaded 3) The form with comma-separated expression list inside the square brackets is only used to call an overloaded The built-in subscript expression E1[E2] is exactly identical to the expression *(E1 + E2) except for its value category(see below) and evaluation order (since C++17): the pointer operand (which may be a result of array-to-pointer conversion, and which must point to an element of some array or one past the end) is adjusted to point to another element of the same array, following the rules of pointer arithmetics, and is then dereferenced. When applied to an array, the subscript expression is an lvalue if the array is an lvalue, and an xvalue if it isn't (since C++11). When applied to a pointer, the subscript expression is always an lvalue. The type
In overload resolution against user-defined operators, for every object type #include <iostream> #include <string> #include <map> int main() { int a[4] = {1, 2, 3, 4}; int* p = &a[2]; std::cout << p[1] << p[-1] << 1[p] << (-1)[p] << '\n'; std::map<std::pair<int, int>, std::string> m; m[{1, 2}] = "abc"; // uses the [{...}] version } Output: [edit] Built-in indirection operatorThe indirection operator expressions have the form
The operand of the built-in indirection operator must be pointer to object or a pointer to function, and the result is the lvalue referring to the object or function to which expr points. A pointer to (possibly cv-qualified) void cannot be dereferenced. Pointers to other incomplete types can be dereferenced, but the resulting lvalue can only be used in contexts that allow an lvalue of incomplete type, e.g. when initializing a reference. In overload resolution against user-defined operators, for every type #include <iostream> int f() { return 42; } int main() { int n = 1; int* pn = &n; int& r = *pn; // lvalue can be bound to a reference int m = *pn; // indirection + lvalue-to-rvalue conversion int (*fp)() = &f; int (&fr)() = *fp; // function lvalue can be bound to a reference } [edit] Built-in address-of operatorThe address-of operator expressions have the form
1) If the operand is an lvalue expression of some object or function type If the operand is the name of an overloaded function, the address may be taken only if the overload can be resolved due to context. See Address of an overloaded function for details. 2) If the operand is a qualified name of a non-static or variant member, e.g. &C::member,
the result is a prvalue pointer to member function or pointer to data member of type In overload resolution against user-defined operators, this operator does not introduce any additional
function signatures: built-in address-of operator does not apply if there exists an overloaded void f(int) {} void f(double) {} struct A { int i; }; struct B { void f(); }; int main() { int n = 1; int* pn = &n; // pointer int* pn2 = &*pn; // pn2 == pn int A::* mp = &A::i; // pointer to data member void (B::*mpf)() = &B::f; // pointer to member function void (*pf)(int) = &f; // overload resolution due to initialization context // auto pf2 = &f; // error: ambiguous overloaded function type auto pf2 = static_cast<void (*)(int)>(&f); // overload resolution due to cast } [edit] Built-in member access operatorsThe member access operator expressions have the form
2) The first operand must be an expression of pointer to complete class type 3,4) The first operand must be an expression of scalar type (see below) The first operand of both operators is evaluated even if it is not necessary (e.g. when the second operand names a static member). The second operand of both operators is a name of (formally, an
id-expression that names) a data member or member function of If a user-defined The expression E1->E2 is exactly equivalent to (*E1).E2 for built-in types; that is why the following rules address only E1.E2. In the expression E1.E2: 1)
if
E1 is evaluated and discarded in both cases;
2) if
E2 is not a mutable member, the cv-qualification of the result is the union of the cv-qualifications of E1 and E2 , otherwise (if E2 is a mutable member), it is the union of the volatile-qualifications of E1 and E2 ;3)
if 4) if 5) if 6) if 7) if
#include <iostream> struct P { template<typename T> static T* ptr() { return new T; } }; template<typename T> struct A { A(int n): n(n) {} int n; static int sn; int f() { return 10 + n; } static int sf() { return 4; } class B {}; enum E {RED = 1, BLUE = 2}; void g() { typedef int U; // keyword template needed for a dependent template member int* p = T().template ptr<U>(); p->~U(); // U is int, calls int's pseudo destructor delete p; } }; template<> int A<P>::sn = 2; int main() { A<P> a(1); std::cout << a.n << ' ' << a.sn << ' ' // A::sn also works << a.f() << ' ' << a.sf() << ' ' // A::sf() also works // << a.B << ' ' // error: nested type not allowed << a.RED << ' '; // enumerator } Output: [edit] Built-in pointer-to-member access operatorsThe member access operator expressions through pointers to members have the form
1) lhs must be an expression of class type 2) lhs must be an expression of type pointer to class type The second operand of both operators is an expression of type pointer to member ( data or
function) of The expression E1->*E2 is exactly equivalent to (*E1).*E2 for built-in types; that is why the following rules address only E1.*E2. In the expression E1.*E2: 1) if
2) if 3) cv-qualification rules are the same as for member of object operator, with one additional rule: a pointer to member that refers to a mutable member cannot be used to modify that member in a const object; 4) if 5) if the dynamic type of 6) if 7) if In overload resolution against
user-defined operators, for every combination of types
where both operands may be cv-qualified, in which case the return type's cv-qualification is the union of the cv-qualification of the operands. #include <iostream> struct S { S(int n): mi(n) {} mutable int mi; int f(int n) { return mi + n; } }; struct D: public S { D(int n): S(n) {} }; int main() { int S::* pmi = &S::mi; int (S::* pf)(int) = &S::f; const S s(7); // s.*pmi = 10; // error: cannot modify through mutable std::cout << s.*pmi << '\n'; D d(7); // base pointers work with derived object D* pd = &d; std::cout << (d.*pf)(7) << ' ' << (pd->*pf)(8) << '\n'; } Output: [edit] Standard librarySubscript operator is overloaded by many standard container classes
The indirection and member operators are overloaded by many iterators and smart pointer classes
No standard library classes overload operator&. The best known example of overloaded operator& is the Microsoft COM class No standard library classes overload operator->*. It was suggested that it could be part of smart pointer interface, and in fact is used in that capacity by actors in boost.phoenix, but is more common in EDSLs such as cpp.react. [edit] Notes
[edit] Defect reportsThe following behavior-changing defect reports were applied retroactively to previously published C++ standards.
[edit] See alsoOperator precedence Operator overloading
Which of the following is accessed by a member function of a class the object of that class all members of a class the public part of a class the private part of a class?Explanation: A member function can access it's class member variables, irrespective of the access specifier in which the member variable is declared.So, a member function can always access the data in the class of which it is a member. So, option (A) is correct.
How do you access members of the class inside a member function?Similar to accessing a data member in the class, we can also access the public member functions through the class object using the dot operator (.) . Similarly we can define the getter and setter functions to access private data members, inside or outside the class definition.
Which specifier should be used for member functions of a class?14. Which access specifier is usually used for data members of a class? Explanation: All the data members should be made private to ensure the highest security of data. In special cases we can use public or protected access, but it is advised to keep the data members private always.
Which among the following is false for a member function of a class Mcq?Which among the following is false, for a member function of a class? Explanation: Member functions must be declared inside class body, though the definition can be given outside the class body. There is no way to declare the member functions outside the class. 12.
|