我有一些关于C++开发人员有关C++的问题。有关C++开发人员有关C++的一些问题
因为几天我在看一些C++代码,我有folwing问题:
- 什么时候使用
Foo::
,Foo.
和Foo->
? - 什么时候使用一个真正的构造函数,并在刚
String a;
(有时我需要做的某事物一样String a("foo");
) - 哪里是这些签名的区别是:
int foo(int a)
和int foo(int &a)
?
我有一些关于C++开发人员有关C++的问题。有关C++开发人员有关C++的一些问题
因为几天我在看一些C++代码,我有folwing问题:
Foo::
,Foo.
和Foo->
?String a;
(有时我需要做的某事物一样String a("foo");
)int foo(int a)
和int foo(int &a)
?::
被使用,也可以显式地指定一个命名空间(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
的引用)作为避免复制的方式,同时仍阻止被调用者修改该对象。
Foo::
- 静态方法
Foo.
- 当你有一个栈对象实例实例方法。 (MyObject obj
)
Foo->
- 实例方法,当你有一个对象指针。 (MyObject* pObj = new MyObject()
)
每当你需要传递一些值给构造函数。
int&
是对int
的参考。 a
范围内的任何更改将影响a
以外的方法。 (相当于ref
在C#)
还请记住,操作员可能会过载。 – Nick 2012-02-21 09:39:47
1:假设你要调用方法
美孚:: theMethod(...)
打电话时为实施例中使用一类Foo的静态方法
Foo.theMethod(...)
是当你有一个名为美孚
Foo-> theMethod(对象...)
是当你有一个指针的名为Foo
2目的:
字符串一个;
调用默认的构造函数,它没有参数
字符串一( “富”)
调用一个重载的构造
3:
INT foo(int & a)
需要对整数进行引用,所以在该方法中您可以操纵一个。
INT FOO(INT A)
进行复印时,操纵它不会有在离开方法之后经过在实际参数的任何影响。
String a
:构建一个空String
对象
String a("foo")
:构建initalized到"foo"
int foo(int a)
一个String
对象:通过值传递a
/复制到FOO。里面FOO如果修改a
,a
不会外富
int foo(int& a)
受到影响:由内而外foo的引用传递a
。如果修改a
,a
也将修改后富结束
问题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.
}
请注意,在第一种情况下,您可以传递任意表达式;在 第二,你必须通过一些东西,称为左值—即 你可以使用类似的表达式(一个名为 变量,或一个取消指针,或命名数组中的元素, 等)后访问的东西。
你试过Google搜索这个问题吗? – triclosan 2012-02-21 09:33:09
我建议你在C++初学者书上投资,因为所有这些(以及更多)都应该在其中解释。 – 2012-02-21 09:34:10
@triclosan:为什么这很重要? Google是比寻求编程答案更好的地方吗? – jalf 2012-02-21 10:17:30