这是定义:
在使用类的面向对象编程中,实例变量是在类中定义的变量(即成员变量)//我明白了这部分
, 类的每个对象都有一个单独的副本。// 这部分我不明白。
一个对象怎么会有一个单独的副本?什么的单独副本?
抱歉问了一些基本问题,我还是菜鸟。
谢谢
这是定义:
在使用类的面向对象编程中,实例变量是在类中定义的变量(即成员变量)//我明白了这部分
, 类的每个对象都有一个单独的副本。// 这部分我不明白。
一个对象怎么会有一个单独的副本?什么的单独副本?
抱歉问了一些基本问题,我还是菜鸟。
谢谢
[评论答案] 实例变量是一个变量,它为声明的每个对象都有一个实例,其中类变量是单个成员变量,对于声明为该类型的所有对象,只有一个成员变量。类变量使用关键字 static,而实例变量则没有!
[ORIGINAL] 当你定义一个类时,它有成员声明。
在定义该类类型的变量之前,不会真正实例化对象(或给定内存空间)。
如果您随后定义了两个该类类型,则这些对象将被赋予它们自己的内存空间,并且每个对象的每个成员实际上都有自己的内存(因此该对象的 2 个单独的实例化)。
现在,每组数据(在对象内)都可以并且确实是单独操作的。
类变量:
http://en.wikipedia.org/wiki/Class_variable
实例变量:
如果您有两个对象,则每个对象都将拥有自己的实例变量副本。即a.x
与 不同b.x
,即使你给它们相同的值。
我又做了一个可怕的蚀刻草图,只好用它来灼伤你的眼睛。如果它能解决任何理解问题,那就太好了!
所以,我们有一个类,叫它Foo
。Foo
有一些静态成员,如图:
x
, y
,z
在顶部,您会看到非对象访问。这意味着我们可以在没有对象的情况下访问这些静态成员。事实上,一个对象甚至不必在访问它们之前创建,因为它们在开始之前就存在main
。
struct Foo {
static int x, y, z;
};
int Foo::x = 3;
int Foo::y = 1;
int Foo::z = 8;
int main() {
std::cout << Foo::y;
Foo::x = 6;
}
接下来,我们还有其他包含两个对象的实例成员的圆圈:
struct Foo {
int a;
int b;
int c;
Foo (int a2, int b2, int c2)
: a (a2), b (b2), c (c2){}
};
int main() {
Foo obj1 (6, 9, 10);
Foo obj2 (3, 2, 4);
std::cout << obj1.a; //outputs 6
std::cout << obj2.a; //outputs 3 - different
obj1.z = 100;
std::cout << obj2.z; //outputs 100 - same
std::cout << Foo::z; //outputs 100
}
我们还可以放入成员函数和静态函数来访问变量:
struct Foo {
int getA() const {return a;}
void setA (int newA) {a = newA;}
static int getX() const {return x;}
static void setY (int newY) {return y;}
static void setB (int newB) {
b = newB; //error: static functions can't access instance members
}
}
int main() {
Foo obj1 (6, 9, 10);
std::cout << obj1.getX(); //outputs 3
Foo::setY (5);
obj1.setA (98);
std::cout << obj1.getA(); //outputs 98
}
回顾一下:
每个对象都可以访问自己的实例成员。一个对象的实例成员不会影响另一个(除非它们是有意的,例如引用)。
两个对象共享同一个静态成员池。这个池是创建的,并且可以在创建任何对象之前使用Foo::
语法或之后使用obj1.
或obj2.
语法进行操作。在某处更改静态成员会影响所有情况。
要控制这些成员的使用,请将它们设为私有并提供访问功能。请注意,静态函数不能访问实例成员。该函数可以在不创建任何对象的情况下使用,那么它应该如何处理实例成员?它没有要更改的特定对象的实例对象池!
为了详细说明最后一点,成员函数会获得一个this
传递给它们的隐式参数,该参数告诉它们在您修改时要修改的变量。a = newA;
实际上等价于this->a = newA;
。然而,静态成员函数没有this
参数,因此无法知道要修改哪个对象。