2012-02-21 7 views
3

У меня есть некоторые вопросы о C++ от разработчика C#.некоторые вопросы о C++ от разработчика C#

уже несколько дней я смотрю на некоторый код C++ и у меня есть folwing вопросы:

  1. когда же используют Foo::, Foo. и Foo->?
  2. , когда я могу использовать настоящий конструктор, и когда только String a; (иногда мне нужно сделать s.th. как String a("foo");)
  3. , где разница между этими подписями: int foo(int a) и int foo(int &a)?
+0

Вы попробовали этот вопрос? – triclosan

+2

Я предлагаю вам инвестировать в книгу начинающих на C++, так как все это (и многое другое) должно быть объяснено в нем. –

+0

@triclosan: почему это имеет значение? Лучше ли Google найти ответы на программирование, чем SO? – jalf

ответ

5

:: используется либо для явного указания имен (std::string, например, для класса строки в пространстве имен std), или для статических членов класс.

. используется так же, как в C#, для обозначения члена класса.

-> Используется с указателями. Если p является указателем на объект obj, то p->x имеет то же значение, что и obj.x.

Когда я использую реальный конструктор и когда просто String a; (иногда мне нужно сделать что-то вроде String a («foo»);)

Когда вам нужно.String a примерно эквивалентен C# 's a = new String() (с оговоркой, что если String типа не-POD, он может содержать неинициализированные члены.)

Если вам нужно a инициализируется определенным значение, вы делаете это. (Либо с String a("foo"), или с String a = "foo")

, где есть разница между этими подписями: INT Foo (INT а) и INT Foo (INT & а)?

& обозначает ссылку. Это не довольно C# ссылка, но есть сходства. В C# у вас есть типы значений и ссылочные типы, а ссылочные типы всегда передаются по ссылке.

В C++ такого различия нет. Каждый тип может быть передан по значению или по ссылке. Тип T& является ссылкой на T. Другими словами, учитывая следующий код:

void foo(int& j); 
void bar(int j); 

int i = 42; 

foo(i); 
bar(i); 

foo получит ссылку на i, что означает, что он может изменить значение i. bar получит копию от i, что означает, что любые его модификации не отражаются на i.

Вы часто используете const T& (ссылка на const T) как способ избежать копирования, в то же время не позволяя вызываемому изменять объект.

0
  1. Foo:: - Статические методы

    Foo. - Instance Методы, когда у вас есть экземпляр объекта стека. (MyObject obj)

    Foo-> - Методы экземпляра, когда у вас есть указатель на объект. (MyObject* pObj = new MyObject())

  2. Всякий раз, когда вам нужно передать какое-либо значение конструктору.

  3. int& является ссылкой на int. Любые изменения в a в пределах метода повлияет на a вне метода. (Эквивалент ref в C#)

+1

Также помните, что операторы могут быть перегружены. – Nick

2

1: Предполагая, что вы для вызова метода

Foo :: theMethod (...)

является, например, используется при вызове статический метод класса Foo

Foo.theMethod (...)

когда у вас есть объект с именем Foo

foo-> theMethod (...)

когда у вас есть указатель на объект с именем Foo

2:

строку;

вызывает конструктор по умолчанию, который не принимает никаких аргументов

строку ("Foo")

называет перегруженный конструктор

3:

Int foo (int & a)

принимает ссылку на целое число, поэтому в рамках метода вы можете манипулировать a.

INT Foo (Int А)

делает копию, манипулируя это не будет иметь никакого эффекта фактического параметра, переданного после выхода из метода.

1
  1. String a: построить пустой String объект

    String a("foo"): построить String объект initalized к "foo"

  2. int foo(int a): передать a по значению/скопировать обув. Внутри обув если изменить a, a не будут затронуты вне обув

    int foo(int& a): передать a по ссылке внутри обув. Если вы изменяете a, a будет также изменить один раз Foo закончился

2

Вопрос 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 —, то есть что-то, с которым вы можете получить доступ позже, с помощью аналогичного выражения (с именем или указателем, указанным в приложении, или элементом в именованном массиве, и т. д.).

Смежные вопросы