函数参数的赋值形式

- (void)viewDidLoad
{
    [super viewDidLoad];
	
    MyClass *myc = [[MyClass alloc] init];
    
    NSLog(@"在刚实例化的时候:");
    NSLog(@"myc.retainCount = %d",myc.retainCount);
    NSLog(@"myc:%@",myc);
    NSLog(@"\n");
    
    [self doSomething:myc];
}

- (void)doSomething:(MyClass *)myClass
{
    NSLog(@"被当作参数传递后:");
    NSLog(@"myc.retainCount = %d",myClass.retainCount);
    NSLog(@"myc:%@",myClass);
}

输出结果:

事实证明,函数参数是通过assign的形式传入函数体内供函数调用的。

### C++ 构造函数与赋值运算符的区别 #### 一、概念差异 构造函数是一种特殊的成员函数,在创建对象被自动调用,其目的是初始化新创建的对象。而赋值运算符则是在两个已有对象之间进行数据传递使用的操作符重载方法。 - **拷贝构造函数**:当需要通过已有的对象来初始化一个新的对象,会调用拷贝构造函数[^2]。 - **赋值运算符**:如果目标对象已经存在,则使用赋值运算符将其内容替换为另一个对象的内容[^3]。 --- #### 二、调用场景对比 | 场景 | 调用方式 | |------|----------| | 创建并初始化一个新对象 | 拷贝构造函数 | | 将现有对象的数据赋给另一个已存在的对象 | 赋值运算符 | 具体来说: 1. 当以下情况发生,会触发拷贝构造函数: - 函数参数按值传递; - 返回局部对象; - 显式地用一个对象去初始化另一个对象[^4]。 2. 对于赋值运算符而言,它会在如下条件下被调用: - 已经声明好的对象重新获得其他对象的值;例如 `objA = objB` 这样的语句中。 --- #### 三、实现细节比较 ##### (1) 拷贝构造函数 通常定义形式如下所示: ```cpp ClassName(const ClassName& other); ``` 需要注意的是,为了避免潜在的风险(比如指针指向同一内存区域),可能还需要考虑深拷贝逻辑而不是默认的浅拷贝。 示例代码展示如何正确编写带资源管理功能的类及其拷贝构造函数: ```cpp class MyClass { private: int* data; public: explicit MyClass(int value) : data(new int(value)) {} ~MyClass() { delete data; } // Copy Constructor with deep copy logic. MyClass(const MyClass& other) : data(new int(*(other.data))) {} }; ``` 上述例子展示了手动分配动态存储空间的情况,并且确保了每次复制都能独立拥有自己的副本。 ##### (2) 赋值运算符 一般形式为: ```cpp ClassName& operator=(const ClassName& rhs); ``` 同样重要的一点是防止自我赋值带来的问题以及执行必要的清理工作后再做实际的赋值动作。 下面给出完整的带有安全机制版本的例子: ```cpp #include <iostream> using namespace std; class String { private: char *str; public: String(): str(nullptr){} String(const char*s){ if(s != nullptr){ this->str=new char[strlen(s)+1]; strcpy(this->str,s); } } ~String(){ cout << "~String()" << endl; delete []this->str; } // Assignment Operator Overloading String& operator= (const String &rhs){ if(&rhs == this)return *this;// Self assignment check delete[] this->str; // Release current resource first. if(rhs.str!=nullptr){ this->str=new char[strlen(rhs.str)+1]; strcpy(this->str,rhs.str); }else{ this->str=nullptr; } return *this; } }; int main(){ String s1("hello"); String s2="world"; s2=s1; } ``` 此程序片段不仅实现了字符串类型的简单封装还包含了对赋值过程中的异常处理措施。 --- ### 总结 综上所述,虽然两者看起来相似但实际上用途完全不同——前者负责构建新的实例后者则是更新现有的实体状态[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值