object c++如何实现反射机制

本文详细介绍了Objective-C中反射机制的应用,包括如何通过字符串创建对象并调用其方法,以及如何获取类的所有属性。文中提供了具体的代码示例,并解释了反射机制在不引入类的情况下实现动态操作的重要性。

开发语言的反射机制为我们提供了发挥想象力的基础,通过反射可以设计出各种5花8门的架构来。

 

参考网上各种资料,Object c++的反射主要依靠下面的2个函数。

 

 

NSClassFromString

 

NSSelectorFromString

 

 

下面直接摆上例子,一目了然。

 

 

(一)通过一个字符串来创建对象并调用对象中的方法。

 

文件:Member.h

 

Cpp代码 复制代码  收藏代码
  1. //  Member.h   
  2. #import <Foundation/Foundation.h>   
  3.   
  4. @interface Member : NSObject {   
  5.     NSString *name;   
  6.     int age;   
  7. }   
  8.   
  9. @property (nonatomic,copy) NSString *name;   
  10. @property int age;   
  11.   
  12.   
  13. @end  
//  Member.h
#import <Foundation/Foundation.h>

@interface Member : NSObject {
	NSString *name;
	int age;
}

@property (nonatomic,copy) NSString *name;
@property int age;


@end
 

文件Member.m

 

Cpp代码 复制代码  收藏代码
  1. //  Member.m   
  2. #import "Member.h"   
  3.   
  4. @implementation Member   
  5.   
  6. @synthesize name,age;   
  7.   
  8. @end  
//  Member.m
#import "Member.h"

@implementation Member

@synthesize name,age;

@end
 

 

 

测试代码文件Sample01.m:

 

Cpp代码 复制代码  收藏代码
  1. #import <Foundation/Foundation.h>   
  2.   
  3. int main (int argc, const char * argv[]) {   
  4.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];   
  5.        
  6.     //定义类名   
  7.     NSString *className=@"Member";   
  8.     //定义方法名   
  9.     //注意:方法名后面要根据参数来设置,这里的setName:,表示setName   
  10.     //     方法后面有1个参数   
  11.     NSString *methodName=@"setName:";   
  12.        
  13.     //取得类并分配内存和初始化   
  14.     id obj=[[NSClassFromString(className) alloc] init];   
  15.     //调用类方法   
  16.     [obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."];   
  17.     //显示   
  18.     NSLog(@"%@",[obj name]);   
  19.        
  20.     [pool drain];   
  21.     return 0;   
  22. }  
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	//定义类名
	NSString *className=@"Member";
	//定义方法名
	//注意:方法名后面要根据参数来设置,这里的setName:,表示setName
	//     方法后面有1个参数
	NSString *methodName=@"setName:";
	
	//取得类并分配内存和初始化
	id obj=[[NSClassFromString(className) alloc] init];
	//调用类方法
	[obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."];
	//显示
	NSLog(@"%@",[obj name]);
	
	[pool drain];
    return 0;
}
 

 

代码执行后,显示如下:

 

 

2012-03-16 17:41:31.962 Sample01[39762:1307] Tom and Jerry.

 

 

 

 

由上面例子发现:

(1)在反射时,不需要使用import引入要反射的类;

(2)在定义反射类方法名时要注意后面的冒号,必须根据参数数量和原类方法名设置。

 

 

 

(二)通过字符串获取类的全部属性。

 

对上面的例子进行调整,如下面代码:(注意:在头部要引入头文件 objc/runtime.h

 

 

Cpp代码 复制代码  收藏代码
  1. #import <Foundation/Foundation.h>   
  2. #import <objc/runtime.h>   
  3.   
  4. int main (int argc, const char * argv[]) {   
  5.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];   
  6.        
  7.     //定义类名   
  8.     NSString *className=@"Member";   
  9.     //定义方法名   
  10.     //注意:方法名后面要根据参数来设置,这里的setName:,表示setName   
  11.     //     方法后面有1个参数   
  12.     NSString *methodName=@"setName:";   
  13.        
  14.     //取得类并分配内存和初始化   
  15.     id obj=[[NSClassFromString(className) alloc] init];   
  16.     //调用类方法   
  17.     [obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."];   
  18.     //显示   
  19.     NSLog(@"%@",[obj name]);   
  20.        
  21.     //定义类属性的数量   
  22.     unsigned propertyCount;   
  23.     //获取对象的全部属性并循环显示属性名称和属性特性参数   
  24.     objc_property_t *properties = class_copyPropertyList([obj class],&propertyCount);   
  25.     for(int i=0;i<propertyCount;i++){   
  26.         objc_property_t prop=properties[i];   
  27.         NSLog(@"property:%s",property_getName(prop));   
  28.         NSLog(@"property_getAttributes:%s",property_getAttributes(prop));   
  29.     }   
  30.        
  31.   
  32.     [pool drain];   
  33.     return 0;   
  34. }  
#import <Foundation/Foundation.h>
#import <objc/runtime.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	//定义类名
	NSString *className=@"Member";
	//定义方法名
	//注意:方法名后面要根据参数来设置,这里的setName:,表示setName
	//     方法后面有1个参数
	NSString *methodName=@"setName:";
	
	//取得类并分配内存和初始化
	id obj=[[NSClassFromString(className) alloc] init];
	//调用类方法
	[obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."];
	//显示
	NSLog(@"%@",[obj name]);
	
	//定义类属性的数量
	unsigned propertyCount;
	//获取对象的全部属性并循环显示属性名称和属性特性参数
	objc_property_t *properties = class_copyPropertyList([obj class],&propertyCount);
	for(int i=0;i<propertyCount;i++){
		objc_property_t prop=properties[i];
		NSLog(@"property:%s",property_getName(prop));
		NSLog(@"property_getAttributes:%s",property_getAttributes(prop));
	}
	

	[pool drain];
    return 0;
}
 

代码执行后,显示结果如下:

 

2012-03-19 16:40:04.345 Sample01[41713:1307] Tom and Jerry.

2012-03-19 16:40:04.350 Sample01[41713:1307] property:age

2012-03-19 16:40:04.352 Sample01[41713:1307] property_getAttributes:Ti,Vage

2012-03-19 16:40:04.354 Sample01[41713:1307] property:name

2012-03-19 16:40:04.355 Sample01[41713:1307] property_getAttributes:T@"NSString",C,N,Vname

 

 

关于属性的特性参数可以参考官方文档说明:

 

Property Type String

You can use the property_getAttributes function to discover the name, the @encodetype string of a property, and other attributes of the property.

The string starts with a T followed by the @encode type and a comma, and finishes with a V followed by the name of the backing instance variable. Between these, the attributes are specified by the following descriptors, separated by commas:

Table 7-1  

Code

Meaning

Declared property type encodings

R

The property is read-only (readonly).

C

The property is a copy of the value last assigned (copy).

&

The property is a reference to the value last assigned (retain).

N

The property is non-atomic (nonatomic).

G<name>

The property defines a custom getter selector name. The name follows the G (for example, GcustomGetter,).

S<name>

The property defines a custom setter selector name. The name follows the S (for example, ScustomSetter:,).

D

The property is dynamic (@dynamic).

W

The property is a weak reference (__weak).

P

The property is eligible for garbage collection.

t<encoding>

Specifies the type using old-style encoding.


 

 

 

【多变量输入超前多步预测】基于CNN-BiLSTM的光伏功率预测研究(Matlab代码实现)内容概要:本文介绍了基于CNN-BiLSTM模型的多变量输入超前多步光伏功率预测方法,并提供了Matlab代码实现。该研究结合卷积神经网络(CNN)强大的特征提取能力与双向长短期记忆网络(BiLSTM)对时间序列前后依赖关系的捕捉能力,构建了一个高效的深度学习预测模型。模型输入包含多个影响光伏发电的气象与环境变量,能够实现对未来多个时间步长的光伏功率进行精确预测,适用于复杂多变的实际应用场景。文中详细阐述了数据预处理、模型结构设计、训练流程及实验验证过程,展示了该方法相较于传统模型在预测精度和稳定性方面的优势。; 适合人群:具备一定机器学习和深度学习基础,熟悉Matlab编程,从事新能源预测、电力系统分析或相关领域研究的研发人员与高校研究生。; 使用场景及目标:①应用于光伏电站功率预测系统,提升电网调度的准确性与稳定性;②为可再生能源并网管理、能量存储规划及电力市场交易提供可靠的数据支持;③作为深度学习在时间序列多步预测中的典型案例,用于科研复现与教学参考。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注数据归一化、CNN特征提取层设计、BiLSTM时序建模及多步预测策略的实现细节,同时可尝试引入更多外部变量或优化网络结构以进一步提升预测性能。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值