Вопрос 1:
Это зависит от того, что Foo
есть. Оператор ::
называется оператором разрешения ; операндом справа должно быть пространство имен или класс , а операнд слева - член пространства имен или класса. Если Foo
класс, Foo::
может быть использован для доступа к статическому члену, или внутри члена производного класса, чтобы получить доступ к члену базового класса: например:
class Foo
{
public:
virtual void f();
static void g();
};
int h()
{
Foo::g();
}
class Derived : public Foo
{
public:
virtual void f()
{
Foo::f(); // Call function in base class...
}
}
Он часто используется для доступа к элементам пространства имен, например std::cout
(объект cout
в пространстве имен std
).
Оператор .
является оператором доступа к члену и требует в качестве левого операнда объекта (или ссылку на объект).Таким образом (с использованием выше определения):
Foo obj;
obj.f();
void i(Foo& rFoo)
{
rFoo.f();
}
Он также может быть использован для доступа к статическим членам, если у вас есть экземпляр:
Foo obj;
obj.g();
->
очень напоминает оператор .
, за исключением что он принимает указатель экземпляра, а не экземпляр, и (очень важно) он может быть перегружен. Таким образом:
Foo* obj;
obj->g();
// And if Ptr is a user defined type with an overloaded
// `operator->` which returns a Foo*
Ptr obj;
obj->g();
Опять же, вы можете также использовать этот синтаксис для доступа к статическому члену, если есть указатель на объект.
Вопрос 2:
Определение String a;
вызывает настоящий конструктор. Вы используете String a;
, если хотите конструктор по умолчанию; тот, у которого нет параметров. Вы используете String a("foo");
, если хотите конструктор, который принимает char const*
(или char const (&)[4]
, но это маловероятно, так как он будет работать только для строкового литерала с ровно тремя символами).
В общем, при определении переменных:
String a; // default constructor...
String a1(); // NOT what it looks like: this is a
// function declaration, and not the
// definition of a variable!!!
String b(x, y, z); // constructor taking x, y and z as arguments...
String c = x; // implicitly convert `x` to String, then
// copy constructor.
Последняя форма является немного сложнее, так как конструктор копирования может быть (и почти всегда) опущены, но законность программы определяется Правило выше: должен быть способ неявного преобразования x
в String
, а String
должен иметь доступный конструктор копирования.
В других контекстах, например. new String()
, форма с пустыми параметрами может использоваться для «построения значений», который является конструктором по умолчанию , если есть определенный пользователем, в противном случае нулевая инициализация.
Вопрос 3:
Первый проходит по значению, и передает копию аргумента в функции . Второй - по ссылке и передает ссылку (которая ведет себя как скрытый, автоматически разыменованный указатель ) к функции. Таким образом:
void f(int a)
{
++ a; // Modifies local copy, has no effect on the argument.
}
void g(int& a)
{
++ a; // Modifies the variable passed as an argument.
}
Обратите внимание, что в первом случае вы можете передать произвольное выражение; в вы должны передать что-то, называемое lvalue —, то есть что-то, с которым вы можете получить доступ позже, с помощью аналогичного выражения (с именем или указателем, указанным в приложении, или элементом в именованном массиве, и т. д.).
Вы попробовали этот вопрос? – triclosan
Я предлагаю вам инвестировать в книгу начинающих на C++, так как все это (и многое другое) должно быть объяснено в нем. –
@triclosan: почему это имеет значение? Лучше ли Google найти ответы на программирование, чем SO? – jalf