What is an Object?(转载)

博客介绍了面向对象编程中对象的概念,对象是能执行特定动作、与程序其他部分交互的组件,可存储自身数据。还阐述了成员数据和成员函数,以及对象和实例的区别,通过中世纪视频游戏示例进行说明,如玩家和怪物对象及其实例。

Objects defined

       So what is an object? An object is a component of a program that knows how to perform certain actions and to interact with other pieces of the program. Functions have previously been described as "black boxes" that take an input and spit out an output. Objects can be thought of as "smart" black boxes. That is, objects can know how to do more than one specific task, and they can store their own set of data. Designing a program with objects allows a programmer to model the program after the real world. A program can be broken down into specific parts, and each of these parts can perform fairly simple tasks. When all of these simple pieces are meshed together into a program, it can produce a very complicated and useful application.

Let's say that we are writing a text-based medieval video game. Our video game will have two types of characters: the players and the monsters. A player has to know the values of certain attributes: health, strength, and agility. A player must also know what type of weapon and what type of armor they possess. A player must be able to move through a maze, attack a monster, and pick up treasure. So, to design this "player object", we must first separate data that the player object must know from actions that the player must know how to execute. The definition for a player object could be:

Player Object:
data:
    health
    strength
    agility
    type of weapon
    type of armor
actions:
    move
    attack monster
    get treasure
END;

Member Data and Member Functions

Data that an object keeps track of is called member data and actions that an object knows how to do are called member functions. Member data is very similar to variables in a regular function in the sense that no other object can get access to that data (unless given permission by the object). Member data keeps its values over the life of an object.

Objects and Instances

There is a very important distinction between an object and an instance of an object. An object is actually a definition, or a template for instances of that object. An instance of an object is an actual thing that can be manipulated. For instance, we could define a Person object, which may include such member data as hair color, eye color, height, weight, etc. An instance of this object could be "Dave" and Dave has values for hair color, eye color, etc. This allows for multiple instances of an object to be created. Let's go back to the medieval video game example and define the monster object.

Monster Object:
data:
   health
   skin thickness
   claws
   tail spikes
actions:
   move
   attack player with claws
   attack player with tail
END;

Now, our game could have one instance of a player:

Player Instance #1:
data:
    health = 16
    strength = 12
    agility = 14
    type of weapon = "mace"
    type of armor = "leather"
END;
and our game could have two instances of monsters:
a tough one:and a weak one:
Monster Instance #1:
data:
   health = 21
   skin thickness = 20
   claws = "sharp"
   tail spikes = "razor sharp"
END;
Monster Instance#2:
data:
   health = 9
   skin thickness = 5
   claws = "dull"
   tail spikes = "quite dull"
END;
Notice how an instance of an object contains information on member data, but holds nothing about member functions. Every instance of the Monster object performs "attack player" the same way. There is a series of steps in this member function. But each instance of the monster has its own value for the member data. In the preceding example, we can tell the two monsters in our game apart, because of their member data. One monster is tough and the other monster is weak.

Let's say that we had a "Battle" function in our game. The pseudocode for it may go something like the following:

Function Battle(parameters: _player = the Player Object instance
                            _monster = the Monster Object instance)
   turn = PLAYER; 
   while ((_player's health > 0) AND (_monster's health > 0)) {
      if (turn == PLAYER){      
         player attack's monster;
         turn = MONSTER;
      }
      else {
         monster attack's player
         turn = PLAYER;
      }
   }
} // END FUNCTION Battle

In the "attack" phase, the attacking person would somehow deduct points from the defending person. Let's say that the player was fighting with the weaker monster. The weaker monster's health value is 9. If the player attacked the monster and did 5 points of damage to the monster, the monster's new health value would be 4. The monster keeps this value as its health value until it is undated again. So if the monster ran away at this point, and later in the game, the player discovered the weaker monster again, it's health value would still be 4.

Summary

Objects are ways of bundling parts of programs into small, manageable pieces. Objects are simply a definition for a type of data to be stored. An instance of an object contains meaningful information, these are manipulated by the program. There can be more than one instance of an object. Instances of objects keep track of information, called member data, or instance variables. This data is kept track of by the instance until it no longer exists. Object instances also know how to perform certain functions, called member functions, or class functions. Every instance of an object performs the same steps when carrying out a member function, although the steps can be influenced by the instances' present member data.
<think>嗯,用户问的是当对象通过引用传递给函数时,C++析构函数的行为。我需要先回忆一下C++中对象传递和析构的基本机制。首先,当对象被传递时,如果是按值传递,会调用拷贝构造函数创建副本,函数结束后副本的析构函数会被调用。但如果是按引用传递,就不会创建新对象,而是直接操作原对象。那析构函数的行为会有何不同呢? 接下来,应该考虑引用传递是否会影响析构函数的调用时机。因为引用只是别名,函数内部使用的仍然是原对象,所以在函数结束时,并不会触发析构,因为对象没有被销毁。析构函数只会在原对象的生命周期结束时被调用,比如离开作用域或被显式删除的时候。 然后,用户可能关心的是,如果函数内部对对象进行了修改,或者对象在函数外被销毁,这些情况对析构的影响。比如,如果函数参数是const引用,延长了临时对象的生命周期,这时候析构会在何时发生。需要引用相关的标准或规则来说明这一点。 还需要考虑智能指针的情况,比如使用std::unique_ptr或std::shared_ptr作为引用参数时,析构函数的行为是否有所不同。例如,引用计数的变化会影响析构的时机,但因为是引用传递,智能指针本身不会被拷贝,所以引用计数不会增加,析构还是由原始指针的所有权决定。 另外,用户可能混淆了传递方式对对象生命周期的影响,需要明确说明按引用传递不会改变对象的生命周期,因此析构函数的调用时机与原对象一致。同时,如果函数内部创建了局部对象,并按引用返回,可能会导致悬空引用,这时候析构函数已经被调用,访问会引发未定义行为。 需要引用相关的规则,比如引用[3]中的“三法则”,但这里可能更适用于需要自定义拷贝控制成员的情况。而析构函数的行为主要与对象的生命周期有关,和传递方式的关系需要分情况讨论。 可能还需要提到,当对象被引用传递到函数中,函数执行完毕后,对象的析构函数不会立即被调用,除非在函数内部有显式删除的操作,但这通常是不常见的。大多数情况下,析构函数的调用仍然取决于原对象的销毁时机。 总结来说,按引用传递对象时,函数不会创建副本,因此不会在函数结束时调用析构函数。析构行为仅与原对象的生命周期相关。需要明确这一点,并举例说明不同情况下的行为差异,比如临时对象、局部对象、智能指针等。</think>在C++中,当对象通过引用传递给函数时,析构函数的行为与常规情况有以下关键特性: ### 1. 引用传递的本质特性 - **无对象拷贝**:函数接收的是原对象的别名,不会触发拷贝构造函数 - **生命周期绑定**:析构时机仍由原对象的作用域决定 $$ \text{void process(const MyClass\& obj)} $$ 此时`obj`与原对象共享生命周期[^1] ### 2. 析构触发条件 | 传递方式 | 副本创建 | 析构触发时机 | |----------|----------|----------------------| | 按值传递 | 是 | 函数结束时 | | 按引用传 | 否 | 原对象销毁时 | ### 3. 典型场景分析 **场景1:局部对象引用** ```cpp void test() { MyClass local_obj; use_object(local_obj); // 传入局部对象引用 } // 此处调用local_obj析构函数 ``` **场景2:临时对象优化** ```cpp use_object(MyClass()); // 临时对象生命周期延长至函数结束 // 函数返回后立即调用析构 ``` **场景3:智能指针引用** ```cpp void process(std::unique_ptr<MyClass>& ptr_ref) { // 操作指针但不转移所有权 } // 不会触发析构,所有权仍属原unique_ptr[^2] ``` ### 4. 需要特别注意的边界情况 1. **悬挂引用风险**:当函数返回后原对象已被销毁 2. **多线程环境**:引用可能被其他线程析构 3. **虚析构函数必要性**:基类引用需声明虚析构函数保证正确析构[^1][^3] ### 5. 最佳实践建议 - 对可能继承的类,始终声明`virtual destructor` - 使用`const reference`避免意外修改 - 对于需要延长生命周期的情况,使用`shared_ptr` - 遵循Rule of Three/Five原则管理资源
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值