2012-02-21 57 views
3

我有一些关于C++开发人员有关C++的问题。有关C++开发人员有关C++的一些问题

因为几天我在看一些C++代码,我有folwing问题:

  1. 什么时候使用Foo::Foo.Foo->
  2. 什么时候使用一个真正的构造函数,并在刚String a;(有时我需要做的某事物一样String a("foo");
  3. 哪里是这些签名的区别是:int foo(int a)int foo(int &a)
+0

你试过Google搜索这个问题吗? – triclosan 2012-02-21 09:33:09

+2

我建议你在C++初学者书上投资,因为所有这些(以及更多)都应该在其中解释。 – 2012-02-21 09:34:10

+0

@triclosan:为什么这很重要? Google是比寻求编程答案更好的地方吗? – jalf 2012-02-21 10:17:30

回答

5

::被使用,也可以显式地指定一个命名空间(std::string,例如,String类的命名空间std),或静态成员一类。

.在C#中使用得很多,指的是类的成员。

->与指针一起使用。如果p是指向对象obj的指针,则p->x具有与obj.x相同的含义。

我什么时候使用真正的构造函数,何时只是String a; (有时我需要做一些像String a(“foo”);)

当你需要。String a大致相当于的a = new String()(需要提醒的是,如果String是一种非POD类型,它可能包含未初始化的成员。)

C#如果你需要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. - 当你有一个栈对象实例实例方法。 (MyObject obj

    Foo-> - 实例方法,当你有一个对象指针。 (MyObject* pObj = new MyObject()

  2. 每当你需要传递一些值给构造函数。

  3. int&是对int的参考。 a范围内的任何更改将影响a以外的方法。 (相当于ref在C#)

+1

还请记住,操作员可能会过载。 – Nick 2012-02-21 09:39:47

2

1:假设你要调用方法

美孚:: theMethod(...)

打电话时为实施例中使用一类Foo的静态方法

Foo.theMethod(...)

是当你有一个名为美孚

Foo-> theMethod(对象...)

是当你有一个指针的名为Foo

2目的:

字符串一个;

调用默认的构造函数,它没有参数

字符串一( “富”)

调用一个重载的构造

3:

INT foo(int & a)

需要对整数进行引用,所以在该方法中您可以操纵一个。

INT FOO(INT A)

进行复印时,操纵它不会有在离开方法之后经过在实际参数的任何影响。

1
  1. String a:构建一个空String对象

    String a("foo"):构建initalized到"foo"

  2. int foo(int a)一个String对象:通过值传递a /复制到FOO。里面FOO如果修改aa不会外富

    int foo(int& a)受到影响:由内而外foo的引用传递a。如果修改aa也将修改后富结束

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 (名称空间std中的cout对象)。

.运算符是成员访问运算符,并且需要一个对象(或对对象的引用)作为左手操作数。因此,(使用上述 定义):

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;;没有参数的那个。 当你想构造函数采用 char const*(或char const (&)[4],但这是不太可能的,因为它 将只适用于具有三个字符的字符串文字)的构造函数时使用String a("foo");

通常,定义当变量:

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. 
} 

请注意,在第一种情况下,您可以传递任意表达式;在 第二,你必须通过一些东西,称为左值—即 你可以使用类似的表达式(一个名为 变量,或一个取消指针,或命名数组中的元素, 等)后访问的东西。