C++与Objective-C的差异(转)

iPhone开发入门(7)— 从C/C++语言到Objective-C语言 博主:易飞扬原文链接 : http://www.yifeiyang.net/iphone-development-introduction-7-from-the-c-c-language-to-objective-c-language/转载请保留上面文字。语法概念SEL,IMP的定义方法的定义Class的定义发送消息与函数调用的不同Target-Action Paradigm 阅读详情

转自:http://www.yifeiyang.net/iphone-development-introduction-7-from-the-c-c-language-to-objective-c-language/

觉得这个文章比较有用就转来了.

iPhone开发入门(7)--- 从C/C++语言到Objective-C语言

Objective-C,通常写作ObjC和较少用的Objective C或Obj-C,是扩充C的面向对象编程语言。所以有一定C/C++语言基础理解和掌握Objective-C也会相应的快些。这回,我们将比较着学习Objective-C语言,掌握其语法并理解其思想。


语法

让我们先来看看C++和Objective-C中对于类的宣言 :

C++
#include "BaseClass.h"
class MyClass : public BaseClass
{
public:
            MyClass();
    virtual ~MyClass();
    virtual int GetValue() const;
    virtual void SetValue(int     inValue);
    bool IsValid() const;
    static MyClass* GetInstance();
private:
    int mValue;
    static MyClass* sInstance;
};
Objective-C
#import "BaseClass.h"
@interface MyClass : BaseClass
{
    int mValue;
}
- (int)getValue;
- (void)setValue:(int)inValue;
- (BOOL)isValid;
+ (MyClass*)getInstance;
@end

通过比较上面两段代码,从语法的角度上我们看到 Objective-C 语言有以下特点:


用 #import 取代了 #include

#import 相当于 C/C++ 语言中的 #include+#pragma once。当头文件嵌套包含的时候,它的作用就发挥出来了。  当某一头文件已经被读取后,又一次被 #include 的时候,#pragma once 这会跳过该次读取。  比如我们在C/C++语言的头文件中常常这样定义,就是为了实现 #pragma once 而做的 :
#ifndef INCLUDED_BASECLASS_H
#include    "BaseClass.h"
#endif
继承的时候没有限定符
    继承都是 public 的。
没有构建和虚构函数
成员变量/函数没有限定符
    成员变量缺省是   private  protected  的,而函数是 public 的。
没有const关键字
没有virtual关键字
    Objective-C 中函数缺省的就是 virtual 的。

接下来再看看具体的实现 :

C++
#include    "MyClass.h"
#include    <assert.h>
MyClass*    MyClass::sInstance = 0;
MyClass::MyClass() : mValue(0)
{
}
MyClass::~MyClass()
{
    mValue = -1;
}
int MyClass::GetValue() const
{
    return (mValue);
}
void MyClass::SetValue(int inValue)
{
    assert(IsValid());
    mValue = inValue;
}
bool MyClass::IsValid() const
{
    return (0 <= inValue && inValue <= 1000);
}
MyClass* MyClass::GetInstance()
{
    if (sInstance == 0) {
        sInstance = new MyClass();
    }
    return (sInstance);
}
Objective-C

#import "MyClass.h"

static MyClass* sInstance = 0;

@implementation MyClass

- (int)         getValue
{
    return (mValue);
}

- (void)setValue:(int)inValue
{
    NSParameterAssert([self isValid]);
    mValue = inValue;
}

- (BOOL)isValid
{
    return (0 <= inValue && inValue <= 1000);
}

+ (MyClass*)getInstance
{
    if (sInstance == 0) {
        sInstance = [MyClass alloc];
    }
    return (sInstance);
}

@end




实例方法
方法前面的“-”是实例方法(类似于C++中的类成员函数)

类方法
前缀为“+”的是类方法(类似于C++中的静态成员函数,或者是全局函数)

类变量
与C/C++语言中的静态变量一样,Objective-C 中的类变量就是以 static 声明的变量。(只在当前定义文件中有效) 如果子类也想参照父类中的类变量的时候,须定义属性参照方法(类方法)。(这与面向对象中的封装概念有所背驰,降低了凝聚度)


单一继承
Objective-C 与 Java 语言一样,都是单一继承。
如果想实现多重继承,可以只用类似Java 中 implements 的方法。(Objective-C 中叫做 protocol)


发送消息
Objective-C 中类似于C/C++中函数调用的地方都被称作“发送消息”。调用某个函数,被称为发送了某个消息。其形式如下图所示 :

C++与Objective-C的差异(转) - ♂苹果 - 眼睛想旅行

 Objective-C的发送消息


方法,SEL,方法实现

Objective-C 中方法,SEL型,实现的关系如如下图所示 :
C++与Objective-C的差异(转) - ♂苹果 - 眼睛想旅行

 Objective-C的方法


概念
SEL,IMP的定义

接下来,我们来看看 Objective-C 语言中的头文件 objc.h 的定义 :

// objc.h

typedef struct objc_class *Class;

typedef struct objc_object {
  Class isa;
} *id;

typedef struct objc_selector  *SEL;
typedef id  (*IMP)(id, SEL, …);
typedef signed char   BOOL;

#define YES (BOOL)1
#define NO  (BOOL)0

#ifndef Nil
#define Nil 0   /* id of Nil class */
#endif

#ifndef nil
#define nil 0   /* id of Nil instance */
#endif

id
  id和void *并非完全一样。在上面的代码中,id是指向struct objc_object的一个指针,这个意思基本上是说,id是一个指向任何一个继承了Object(或者NSObject)类的对象。需要注意的是id是一个指针,所以你在使用id的时候不需要加星号。比如id foo=nil定义了一个nil指针,这个指针指向NSObject的一个任意子类。而id *foo=nil则定义了一个指针,这个指针指向另一个指针,被指向的这个指针指向NSObject的一个子类。


 

C++与Objective-C的差异(转) - ♂苹果 - 眼睛想旅行

 
Objective-C的Object

nil

nil和C语言的NULL相同,在objc/objc.h中定义。nil表示一个Objctive-C对象,这个对象的指针指向空(没有东西就是空)。

Nil

首字母大写的Nil和nil有一点不一样,Nil定义一个指向空的类(是Class,而不是对象)。

SEL

SEL是“selector”的一个类型,表示一个方法的名字。比如以下方法:

-[Foo count] 和 -[Bar count] 使用同一个selector,它们的selector叫做count。

在上面的头文件里我们看到,SEL是指向 struct objc_selector的指针,但是objc_selector是什么呢?那么实际上,你使用GNU Objective-C的运行时间库和NeXT Objective-C的运行运行时间库(Mac OS X使用NeXT的运行时间库)时,它们的定义是不一样的。实际上Mac OSX仅仅将SEL映射为C字符串。比如,我们定义一个Foo的类,这个类带有一个- (int) blah方法,那么以下代码:

NSLog (@"SEL=%s", @selector(blah));

会输出为 SEL=blah。说白了SEL就是返回方法名。

这样的机制大大的增加了我们的程序的灵活性,我们可以通过给一个方法传递SEL参数,让这个方法动态的执行某一个方法;我们也可以通过配置文件指定需要执行的方法,程序读取配置文件之后把方法的字符串翻译成为SEL变量然后给相应的对象发送这个消息。

在 Objective-C 运行时库中,selector 是作为数组来管理的。这都是从效率的角度出发:函数调用的时候,不是通过方法名字比较而是指针值的比较来查找方法,由于整数的查找和匹配比字符串要快得多,所以这样可以在某种程度上提高执行的效率。

这样就必须保证所有类中的 selector 须指向同一实体(数组)。一旦有新的类被定义,其中的 selector 也需要映射到这个数组中。

实际情况下,总共有两种 selector 的数组:预先定义好的内置selector数组和用于动态追加的selector数组。


内置selector
简单地说,内置的selector就是一个大的字符串数组。定义在objc-sel-table.h文件中:

#define NUM_BUILTIN_SELS 16371
/* base-2 log of greatest power of 2 < NUM_BUILTIN_SELS */
#define LG_NUM_BUILTIN_SELS 13
static const char * const _objc_builtin_selectors[NUM_BUILTIN_SELS] = {
    ".cxx_construct",
    ".cxx_destruct",
    "CGColorSpace",
    "CGCompositeOperationInContext:",
    "CIContext",
    "CI_affineTransform",
    "CI_arrayWithAffineTransform:",
    "CI_copyWithZone:map:",
    "CI_initWithAffineTransform:",
    "CI_initWithRect:",
    "CI_rect",
    "CTM",
    "DOMDocument",
    "DTD",
    ...
}; 
可以看到,数组的大小NUM_BUILTIN_SELS定义为16371。字符串按照字母顺序排序,简单的都是为了运行时检索的速度(二分法查找)。
从定义好的 selector 名称我们可以看到一些新的方法名称,比如 CIConetext,CI开头的方法是由Tiger开始导入的程序库。
每次系统更新的时候,这个数组也是需要更新的。
动态追加selector
另一个用于动态追加的 selector,其定义在 objc-sel.m 和 objc-sel-set.m  文件中
新的 selector 都被追加到 _buckets 成员中,其中追加和搜索使用 Hash 算法。
static struct __objc_sel_set *_objc_selectors = NULL;
struct __objc_sel_set {
    uint32_t _count;
    uint32_t _capacity;
    uint32_t _bucketsNum;
    SEL *_buckets;
};
IMP
从上面的头文件中我们可以看到,IMP定义为
id (*IMP) (id, SEL, …)。

这样说来,IMP是一个指向函数的指针,这个被指向的函数包括id(“self”指针),调用的SEL(方法名),再加上一些其他参数。说白了IMP就是实现方法。

我们取得了函数指针之后,也就意味着我们取得了执行的时候的这段方法的代码的入口,这样我们就可以像普通的C语言函数调用一样使用这个函数指针。当然我们可以把函数指针作为参数传递到其他的方法,或者实例变量里面,从而获得极大的动态性。我们获得了动态性,但是付出的代价就是编译器不知道我们要执行哪一个方法所以在编译的时候不会替我们找出错误,我们只有执行的时候才知道,我们写的函数指针是否是正确的。所以,在使用函数指针的时候要非常准确地把握能够出现的所有可能,并且做出预防。尤其是当你在写一个供他人调用的接口API的时候,这一点非常重要。


方法的定义

在头文件 objc-class.h 中,有方法的定义 :

typedef struct objc_method *Method;

struct objc_method {
    SEL method_name;
    char *method_types;
    IMP method_imp;
};

    这个定义看上去包括了我们上面说过的其他类型。也就是说,Method(我们常说的方法)表示一种类型,这种类型与selector和实现(implementation)相关。

最初的SEL是方法的名称method_name。char型的method_types表示方法的参数。最后的IMP就是实际的函数指针,指向函数的实现。
Class的定义

Class(类)被定义为一个指向struct objc_class的指针,在objc/objc-class.h中它是这么定义的:

struct objc_class {
  struct objc_class *isa;                /* metaclass */
  struct objc_class *super_class;        /* 父类 */
  const char *name;                      /* 类名称 */
  long version;                          /* 版本 */
  long info;                             /* 类信息 */
  long instance_size;                    /* 实例大小 */
  struct objc_ivar_list *ivars;          /* 实例参数链表 */
  struct objc_method_list **methodLists; /* 方法链表 */
  struct objc_cache *cache;              /* 方法的缓存 */
  struct objc_protocol_list *protocols;  /* protocol链表 */
};
由以上的结构信息,我们可以像类似于C语言中结构体操作一样来使用成员。比如下面取得类的名称:

Class cls;
cls = [NSString class];

printf("class name %s\n", ((struct objc_class*)cls)->name);

发送消息与函数调用的不同
Objective-C的消息传送如下图所示 :

C++与Objective-C的差异(转) - ♂苹果 - 眼睛想旅行

 

Objective-C的消息传送

发送消息的过程,可以总结为以下内容 :


首先,指定调用的方法
为了方法调用,取得 selector

源代码被编译以后,方法被解释为 selector。这里的 selector 只是单纯的字符串。
消息发送给对象B
消息传送使用到了 objc_msgSend 运行时API。这个API只是将 selector 传递给目标对象B。
从 selector 取得实际的方法实现
首先,从对象B取得类的信息,查询方法的实现是否被缓存(上面类定义中的struct objc_cache *cache;)。如果没有被缓

存,则在方法链表中查询(上面类定义中的struct objc_method_list **methodLists;)。


执行
利用函数指针,调用方法的实现。这时,第一个参数是对象实例,第二个是 selector。


传送返回值
利用 objc_msgSend API 经方法的返回值传送回去。


简单地从上面发送消息的过程可以看到,最终还是以函数指针的方式调用了函数。为什么特意花那么大的功夫绕个大圈子呢?1

这些年,随着程序库尺寸的扩大,动态链接库的使用已经非常普遍。就是说,应用程序本身并不包括库代码,而是在启动时或者运行过程中动态加载程序库。这样一来一方面可以减小程序大小,另一方面可以提升了代码重用(不用再造轮子)。但是,随之带来了向下兼容的问题。

如果程序库反复升级,添加新的方法的时候,开发者与用户间必须保持一致的版本,否则将产生运行时错误。一般,解决这个问题是,调用新定义的方法的时候,实现检查当前系统中是否存在新方法的实现。如果没有,跳过它或者简单地产生警告信息。 Objective-C中的respondsToSelector:方法就可以用来实现这样的动作。

但是,这并不是万全的解决方案。如果应用程序与新的动态程序库(含有新定义的API)一起编译后,新定义的API符号也被包含进去。而这样的应用程序放到比较旧的系统(旧的动态程序库)中运行的时候,因为找不到链接符号,程序将不能启动。这就是 win32系统中常见的「DLL地域」。

为了解决这个问题,Objective-C 编译得到的二进制文件中,函数是作为 selector 来保存的。就是说,不管调用什么函数,二进制文件中不会包含符号信息。为了验证 Objective-C 编译的二进制文件是否包含符号信息,这里用 nm 命令来查看。

源代码如下 :

int main (int argc, const char * argv[])
{
    NSString*   string;
    int         length;
    string = [[NSString alloc] initWithString:@"Objective-C"];
    length = [string length];

    return  0;
}

这里调用了 alloc、initWithString:、length 等方法。
% nm Test
         U .objc_class_name_NSString
00003000 D _NXArgc
00003004 D _NXArgv
         U ___CFConstantStringClassReference
00002b98 T ___darwin_gcc3_preregister_frame_info
         U ___keymgr_dwarf2_register_sections
         U ___keymgr_global
0000300c D ___progname
000025ec t __call_mod_init_funcs
000026ec t __call_objcInit
         U __cthread_init_routine
00002900 t __dyld_func_lookup
000028a8 t __dyld_init_check
         U __dyld_register_func_for_add_image
         U __dyld_register_func_for_remove_image
...

可以看到,这里没有alloc、initWithString:、length3个方法的符号。所以,即使我们添加了新的方法,也可以在任何新旧系统中运行。当然,函数调用之前,需要使用 respondsToSelector: 来确定方法是否存在。正是这样的特性,使得程序可以运行时动态地查询要执行的方法,提高了 Objective-C 语言的柔韧性。

Target-Action Paradigm
Objective-C 语言中,GUI控件对象间的通信利用 Target-Action Paradigm。不像其他事件驱动的 GUI 系统实现的那样,需要以回调函数的形式注册消息处理函数(Win32/MFC,Java AWT, X Window)。Target-Action Paradigm 完全是面向对象的事件传递机制。

例如用户点击菜单的事件,用Target-Action Paradigm来解释就是,调用菜单中被设定目标的Action。这个Action对应的方法不一定需要实现。目标与Action的指定与方法的实现没有关系,源代码编译的时候不会检测,只是在运行时确认(参考前面消息传送的机制)。

运行时,通过respondsToSelector: 方法来检查实现的情况。如果有实现,那么使用performSelector:withObject:来调用具体的Action,像是下面的代码:

// 目标对象
id target;
// 具体Action的 selector
SEL action;
...
// 确认目标是否实现Action
if ([target respondsToSelector:actioin]) {
    // 调用具体Action
    [target performSelector:action withObject:self];
}
通过这样的架构,利用 setTarget: 可以更该其他的目标,或者 setAction: 变换不同的Action。实现动态的方法调用。
 
 

1. C/C++语言中用回调函数(callback)的概念来实现程序的动态语义,一般该回调函数都是全局或静态的函数,使用Thunk的方法可以将类的成员函数作为回调函数来使用—利用平台相关的技术将对象实例(this指针)传递给调用端。

相关文章
iPhone开发之深入浅出 (5) --- ARC之Outlet与弱引用 - (2012-03-08)
iPhone开发之深入浅出 (4) --- ARC之循环参照 - (2012-03-01)
iPhone开发之深入浅出 (3) --- ARC之前世今生 - (2012-02-19)
iPhone开发之深入浅出 (2) --- ARC之@property使用 - (2012-01-04)
iPhone开发之深入浅出 (1) --- ARC是什么 - (2012-01-01)
iPhone开发技巧之调试篇(3)--- 程序Crash后的调试技巧 - (2011-11-06)
iPhone开发之游戏篇(3)--- cocos2d的Actions构成 - (2010-07-05)
iPhone开发之游戏篇(2) --- cocos2d的Actions - (2010-07-03)
iPhone开发之游戏篇(1) --- cocos2d的基本概念 - (2010-07-01)
iPhone开发进阶(11)--- 多线程的使用与注意事项 - (2010-03-09)
iPhone开发进阶(10)--- 在程序中使用 GPS - (2010-03-07)
iPhone开发进阶(9)--- 用SQLite管理数据库 - (2010-03-06)
iPhone开发进阶(8)--- 检测屏幕触摸事件 - (2010-03-04)
iPhone开发进阶(7)--- 利用ModalViewController切换View - (2010-03-02)
iPhone开发进阶(6)--- 编程定制UIButton - (2010-02-27)
iPhone开发进阶(5) --- 编程定制UIViewController - (2010-02-25)
iPhone开发进阶(4) --- 使用Makefile自动编译iPhone程序 - (2010-02-23)
iPhone开发进阶(3) --- iPhone应用程序的启动过程 - (2010-02-21)
iPhone开发进阶(2) --- iPhone应用程序/项目的构成 - (2010-02-19)
iPhone开发进阶(1) --- 深入理解iPhone OS/SDK与Objective-C 2.0 - (2010-02-17)
iPhone、Android、Symbian … 移动设备应用程序开发的趋势与对策 - (2010-02-14)
使用org-mode来GTD(3)--- iPhone中使用org-mode - (2010-02-06)
iPhone开发入门(11)--- 在App Store上发布程序 - (2010-01-21)
iPhone开发入门(10)--- 设备上运行程序 - (2010-01-19)
iPhone开发入门(9)--- 实际开发中的应用技巧 - (2010-01-16)

Objective-C 基础入门(一) 目录 一、什么是Objective-C? Hello world Tips: 二、Objective-C的类 1.新建一个OC类 self 指针 Tips: 2.NSString 创建实例 NSString方法 3.NSArray 创建数组 遍历数组 NSMutableArray 4.属性 声明属性 属性的特性 5.继承 创建 覆盖方法 super... 阅读详情

相关推荐

Objective-C语言简介

Objective-C对“接口”功能进行了扩展,其中包括:用于访问代码库和编译器中运行的各种外部语言(编译器, Python、 C#等)以及通过 Web服务器与应用程序进行通信的外部编译工具,如:使用Objective-C编译器可以为运行在 Linux内核上且不需要任何服务器支持的 Web服务器(如: OpenWrite)以及其他软件工具(如: JavaScript)提供更多支持。此外,对于运行在 RISSI/CSS等多种标准设备上的应用程序,Objective-C也有其独特之处。

戴子雯的博客 1800

Objective-C 与 C++ 的区别

一 下面总结一下 Objective-C 与 C++ 的区别: 1, 两者最大的相同便是: 都是从 C 演化而来的面向对象语言, 两者都兼容标准 C 语言. 2, 两者最大的不同便是: Objective C 提供了运行期动态绑定机制, 而 C++ 是编译时静态绑定, 并通过嵌入类(多重继承)和虚函数(虚表)来模拟实现. Objective C 在语言

ji5ji的专栏 1万+

Objective-C与C语言关系解析:从语法到苹果开发生态

C语言作为编译型语言的代表,其语法结构和指针操作奠定了现代编程语言的基础。通过引入Smalltalk的消息传递机制,Objective-C在C语言之上构建了动态的面向对象模型,实现了运行时多态和动态绑定。这种设计使得Objective-C能够与C++代码混合编译,形成Objective-C++模式,为高性能计算和复用现有C++库提供了技术路径。在苹果开发生态中,这一技术价值体现在Cocoa框架的构建和Xcode工具链的深度整合上,使得开发者能够高效构建macOS和iOS应用。本文围绕C系语言谱系、Objec

356

Object-C 与C/C++的区别

1)Object C 的类只能继承一个类,不能继承多个类,如果要实现类似多个继承,需要使用Category和Extension, Extension是没有名字的Category,也就是匿名Category。 2)Object C从2011年引入了Automatic Reference Counting (ARC),支持垃圾收集,不需要担心内存泄露的问题;而C++依然不支持,需要自己手工管理内存...

jimmyleeee的专栏 7695

黑马程序员——Objective-C语言知识整理——Objective-C语言基础知识总结

Objective-C语言基础知识以及与C语言的差异

geek_1993的博客 1769

Objective-C调用C++文件 编程

接下来,我们创建一个名为"ObjectiveCClass.h"的Objective-C头文件,用于声明我们的Objective-C类和方法。在这个示例中,我们创建了一个名为ObjectiveCClass的Objective-C类,它包含一个名为"invokeCPPMethod"的方法,该方法将调用我们在C++文件中定义的cppMethod。在这个示例中,我们创建了一个简单的C++类,名为CPPClass,它包含一个名为"cppMethod"的方法。在这个示例中,我们只是简单地在控制台打印一条消息。

CodeWWWCode的博客 393

十分钟让你明白Objective-C的语法(和Java、C++的对比)

很多想开发iOS,或者正在开发iOS的程序员以前都做过Java或者C++,当第一次看到Objective-C的代码时都会头疼,Objective-C的代码在语法上和Java, C++有着很大的区别,有的同学会感觉像是看天书一样。不过,语言都是相通的,有很多共性。下面列出Objective-C语言的语法和Java,C++的对比,这样你就会很容易Objective-C的语法是怎么回事了。先目睹一下Ob

空杯子 27万+

Objective-C与C++跨语言调用实践指南

在C++中,命名空间是一种封装符号名称(如类、函数和变量等)的方式,以便在不同的库或模块间避免名称冲突。它们是由关键字namespace定义的。通过将代码组织到不同的命名空间中,开发者可以使用相同的名称来标识不同模块中的实体。在面对大型项目或使用多个库时,命名空间显得尤为重要,因为它们可以大大降低名称冲突的风险。命名空间可以嵌套,这意味着一个命名空间可以包含另一个命名空间。这允许开发者创建层次化的结构,从而进一步隔离名称并更好地组织代码。当使用嵌套命名空间中的元素时,需要指定其完整路径。

weixin_35045970的博客 1289

【Objective-C】从C++转向Objective-C的全面指南

Objective-C初学者请进(尤其是从C++转过来的)

qq_33868975的博客 1158

Objective-C与C++混合编程技术详解

Objective-C++ 是 Xcode 编译器(Clang)支持的一种语言扩展,允许开发者在.mm文件中混合使用 Objective-C 和 C++。这种语言结合了 OC 的动态特性和 C++ 的静态特性,是实现混编开发的关键。@end@endpublic:private:// 模拟耗时计算在混编项目中,常见的链接错误包括:Xcode默认提供两种构建配置:Debug:用于调试,包含调试信息;Release:用于发布,优化代码性能。

weixin_29041443的博客 711

从零搭建Synopsys EDA环境:Ubuntu系统下的完整安装与避坑指南

本文详细介绍了在Ubuntu系统下从零搭建Synopsys EDA环境的完整流程,包括系统配置、安装文件准备、核心工具安装、License配置及常见问题排查。特别针对数字IC设计场景,提供了VCS、Verdi、Design Compiler等EDA Tools的安装避坑指南和性能优化建议,帮助开发者高效搭建稳定的开发环境。

weixin_33738982的博客 491

Object-c与c++差异

Object-c与c++差异  单一继承:Objective-C不支持多重继承,(同Java和Smalltalk),而C++语言支持多重继承。       动态:Objective-C是动态定型(dynamicaly typed)所以它的类库比C++要容易操作。Objective-C 在运行时可以允许根据字符串名字来访问方法和类,还可以动态连接和添加类。 C++  跟从面向对象编程里的

零度畅想 5777

解决MATLAB2020B关于找不到vs2019C++编译器问题

解决MATLAB2020B关于找不到vs2019C++编译器问题

wcm2577的博客 7606

十分钟让你明白Objective-C的语法(和Java、C++的对比)【转】

http://blog.youkuaiyun.com/totogo2010/article/details/7632384

xlaaa111的专栏 340

告别GitHub!手把手教你用Gitblit在Windows 10上搭建私人局域网Git服务器(附SourceTree配置)

本文详细介绍了如何在Windows 10环境下使用Gitblit搭建私有Git服务器,实现局域网内高效代码协作。通过轻量级的Gitblit解决方案,开发者可以享受数据完全自主、离线可用性和局域网高速访问等优势。文章包含从环境准备、安装部署到SourceTree配置的全流程指南,特别适合金融、医疗等敏感行业团队使用。

weixin_30430169的博客 281

0.1 专栏导读:为什么需要从 MM 理解 HMM

本文探讨了GPU计算框架中CPU与GPU内存管理的困境,介绍了Linux内核的HMM(Heterogeneous Memory Management)解决方案。传统显式拷贝模型存在编程复杂、指针失效等问题,而HMM通过共享虚拟地址空间、自动页面迁移等机制实现透明内存管理。文章分析了HMM依赖的Linux内存管理基础设施,包括页表遍历、MMU通知、ZONE_DEVICE等核心组件,并梳理了从经典MM到支持异构设备的进化历程。最后给出了学习HMM的8层知识体系,强调理解底层MM机制是掌握HMM的关键。

图形/计算GPU的驱动与虚拟化技术分享园地 765

C++转向Objective-C需要注意的地方(基础)。

部分摘自《Objective-C基础教程》高朝勤 杨越 刘霞译,本人添加一些代码和图片,更容易理解。 参考《深度探索C++对象模型》 从C++转向Objective-C Objective-C中没有多重继承、命名空间、运算符重载、模板、类变量、抽象类、STL等结构。但是Objective-C提供了相似的结构。 Objective-C没有C++中的构造函数、拷贝构造和析构函数是最明智的!当然

郭晓东的专栏 2215

基于高光谱的物质反演与分类 — 技术文章(原理详解 + 深度代码实现)

高光谱遥感 / 近场光谱采集产生逐像素上百波段的光谱曲线,是物质识别与定量反演(abundance / composition estimation)和语义分类(landcover / material class)的一把利器。本文第一部分对常用模型(线性混合模型、非线性辐射传输、稀疏反演、降维与特征选择、分类器/神经网络)进行数学推导与理论分析;第二部分给出两套完整实现:A. 基于 LMM 的约束最小二乘 / 稀疏反演流水线(含端到端评估);

VectorShift的博客 220

Objective-C、C与C++的区别

【代码】Objective-C、C与C++的区别。

qq_42757463的博客 1338

大模型工作流Dify面试题及参考答案

设计一个基于 Dify 的智能摘要与重点提取 Agent,需结合Prompt 工程、模型能力配置和工作流优化,确保对长文本的高效解析和关键信息提炼。1. 明确任务需求与输入输出输入:长文本内容(如文章、报告、会议记录)或文本 URL输出摘要:简洁概括原文核心内容,控制在原文长度的 10%-20%重点列表:分点列出关键数据、结论、行动项等可选:关键词提取、情感倾向分析示例场景输入:一篇 5000 字的行业报告。

大模型大数据攻城狮的专栏 2510

单智能体篇:Prompt工程艺术

模型在接收到 Prompt 时会自动扮演“角色”,角色定义的好坏直接影响智能体输出的风格和专业性。角色定义的重要性让智能体具备明确身份,例如“你是一位专业理财顾问”或“你是一个幽默的文案创作助手”。角色限定了模型知识输出的范围,使回答更专业、更贴合预期。实战示例模糊Prompt给我一些投资建议。你可以投资股票或者基金。优化Prompt你是一位具有10年经验的专业理财顾问,请给我针对30岁男性,年收入20万,风险偏中等的投资组合建议。

公众号:AI前沿侦探 1304

Objective-C和C++语法比较

1)实例方法和对象方法 C++语言中,对象方法的写法可能是: void hello(bool ishello) { ...... } C++语言中,类的方法的写法可能是: static void hello(bool ishello) { ...... } 用Objective-C写出来的对象方法就是 -(void) hello:(BOOL)ishello { ...... } 用Objective-C写出来的类方法就是 +(void) hello:(BOOL)ishello { ......

thehunters的专栏 2031

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Objective-C初学注记(c++ -> obj-c)

初学Objective-C,第一次见到这么反人类的语言。。。 Objective-C是C语言的严格超集,与C++不同,完全兼容C语言。任何原始的C语言程序不经修改就可以直接通过Objective-C编译器,在Objective-C中使用C语言代码也是完全合法的。 C++相对于C语言可以说是一门独立的语言,但Objective-C严格来说不能算是独立的语言,实际上只是一组由C语言写成的运行库。O

言の叶の庭 921

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C预处理器-1(CPP -C PreProcessor)

C 预处理器实现了一种宏语言,这种宏语言用于在 C、C++ 和 Objective - C 程序编译之前对它们进行转换。它自身也有独立的用途。1 概览C 预处理器,通常被称为 “cpp”,是一种 “宏处理器”。在编译之前,C 编译器会自动使用它来转换你的程序。之所以称它为宏处理器,是因为它允许你定义 “宏”,而宏是较长结构的简短缩写形式。C 预处理器旨在仅用于处理 C、C++ 和 Objective-C 源代码。过去,它曾被滥用来作为通用的文本处理器。

snow_feeling的专栏 1303

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Objective-C 和C++的比较

<br />form http://topic.youkuaiyun.com/u/20091212/14/eed674bc-b074-4269-8450-f9ca659103c0.html<br /> <br />1.  最大的相同:都是从c演化过来的面向对象语言。<br />2.  最大的不同:c++是静态语言,而OC是动态类型识别语言?OC提供了运行期动态绑定机制。<br />     OC里,把消息发到一个对象上,如果对象不能处理此消息,也无所谓。<br />     而c++中,则会crash.<br /> <

gyj_freedom的专栏 1095
上一篇: cocos2d开发工具大全(转)
下一篇: 关于cocos2d中的cpp宏(转)
woodcol
博客等级 码龄19年 288粉丝 429原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值