运用本地c/c++提高iOS功能 之四51CTO博客 - AG环亚娱乐

运用本地c/c++提高iOS功能 之四51CTO博客

2019-03-06 10:20:30 | 作者: 鸿云 | 标签: 运用,可以,办法 | 浏览: 1636

c++编程


c++是c的超集,所以这儿你将会学到更多的技能。和Objective-C比较,c++有许多不同的概念和语法,虽然他们都是面向目标的编程言语。他们有许多重要的不同之处:类,指针,多重承继,内存办理,和模板。


class类


这点和Objective-C相似,一个类有两个文件:一个是头文件,另一个是完成文件。你相同可以指定private和public的成员或办法。下面是声明一个类的头文件的规范办法:


class Cat {  

   public:

           // public accessors
           unsigned int GetAge();
           void SetAge(unsigned int Age);

           Cat ();
           Cat (int initialAge);~Cat();

           // public member functions

           void Meow();


           // private member data

   private:

           unsigned int itsAge;

};


// GetAge, Public accessor function

// returns value of itsAge member

unsigned int Cat::GetAge() {

       return itsAge;

}


// returns sets itsAge member
void Cat::SetAge(unsigned int age) {

       // set member variable its age to

       // value passed in by parameter age

       itsAge = age;

}


// action: Prints "meow" to screen

void Cat::Meow() {

       cout << "Meow.\n";

}


int main() {  

   Cat cat;

   cat.Meow();

}


你可以看到,public和private声明可以分隔放在不同当地,就像Objective-C中界说头文件时运用的修饰符@private和@public。关于类的完成,你需求在办法的前面加上类的称号,来标明办法是归于这个类的。


关于拜访和设置办法,你需求显现的声明他们:


unsigned int GetAge();
void SetAge(unsigned int Age);


为了创立一个Cat目标,你只需求声明Cat cat;然后调用办法cat.Meow();可是目标只存在函数的部分规模内部。


关于内存办理,你需求一起声明结构函数和析构函数。假如没有声明你自己的结构函数,编译器会运用一个没有参数的默许结构函数。



留意:假如声明晰自己的结构函数,请记住也要声明析构函数,即便它没有做什么工作。恪守这个预订对错常好的。假如运用Cat cat创立Cat的一个新目标,你需求一个默许结构函数。




指针和内存办理


假如你想要在程序其他当地运用你新创立的目标,在c++中,你需求在自在存储区中请求分配内存。这个目标会一向存在,直到你显现的在内存中把它删去,就像c言语相同。为了声明指向一个包含整型值的内存地址指针,你可以像这样:


int *pInt;
pInt = new int;

*pInt = 72;


分配和开释一个目标,你可以运用new和delete关键字。


Cat *pCat = new Cat;

pCat->SetAge(5);

delete pCat;
pCat = 0;



留意:假如你delete同一个指针两次,你的运用会溃散。假如你在重新分配之前没有delete它,会有内存走漏。




承继


比较于Objective-C,c++承继的概念愈加杂乱。你可以像正常相同运用承继,复写,多态。仅有不同的是virtual和pure virtual办法。


class Dog : Mammal {

}


Dog类承继了Mammal类的一切特点和办法,一起它可以有自己的特点和办法。当Dog目标被创立的时分,Mammal的结构函数先调用,然后在调用Dog的结构函数。


c++承继中有一个十分重要的概念:你只可以复写virtual办法。关于其他办法,你只能承继而不能复写。在父类和子类中可以有两个同名的办法,可是不存在复写和多态。关于virtual办法,主张在必要的时分在子类中进行复写。c++中办法默许的修饰符对错virtual的。有两种类型的虚函数:虚函数和纯虚函数。


#include "stdafx.h"

#include "stdio.h"

using namespace System;

class Animal {

   public:

           virtual void Speak() = 0;

           virtual void Eat();
           void Run();

};

void Animal::Eat(){

       printf("Animal eats\n");

}

void Animal::Run(){

   printf("Animal runs\n");

}


class Dog : Animal{
   public:

           void Eat();

           void Speak();

           void Run();

};

void Dog::Eat(){

       printf("Dog eats\n");

}

void Dog::Run(){

       printf("Dog runs\n");

}

void Dog::Speak(){

   printf("Dog speaks\n");

}

int main(){

   Animal *dog1 = (Animal *) new Dog;

   dog1->Run();

   dog1->Speak();

   dog1->Eat();

   getchar();

}


关于虚函数,在父类中你可以有它的完成;可是关于纯虚函数,你只能声明。Eat办法是虚函数,而Speak是纯虚函数。在子类中,这两个办法都需求复写。


由于Run不是虚函数,子类不需求复写。因而main函数的输出将是


Animal Runs

Dog Speaks

Dog Eats



多重承继


在c++中,你的类可以承继许多父类,因而你可以重用更多的特点和办法。例如,Teacher类一起承继Employee和Person类,如如9-4。


你可以经过下面这样进行多重承继


class Teacher : public Person, public Employee {

}


多重承继存在一个遍及的问题:当两个父类有相同的办法时。例如,Pesron和Employee两个类都声明晰GetIncome办法。因而,当你在Teacher目标中调用此办法时,你有必要显现的指定是调用哪个父类的办法。


假如你仅仅这样写


int currentIncome = pTeacherGetIncome();


你会得到一个编译过错


Member is ambiguous: ‘Person::GetIncome’ and ‘Employee::GetIncome’


你需求显现的指明调用哪个父类的函数来消除这个二义性。


int currentIncome = pTeacherEmployee::GetIncome();



模板


在c++中,你可以界说类或办法只接纳某种指定的类型。例如,你可以界说一个办法,只接纳两个同类型的参数进行比较然后回来成果。


template <class T>
T GetMax (T a, T b) {

   return (a>b)? a : b;

}

int main () {
   int i=5, j=6, k;

   long l=10, m=5, n;

   k=GetMax<int>(i,j);

   n=GetMax<long>(l,m);

   return 0;

}


经过界说一个模板办法,你可以保证a和b是相同的数据类型,这样他们就可以进行比较。你可以在类中也进行相同的操作。


template <class T>

class mypair {

      T a, b;

       public:

               mypair (T first, T second){

                   a=first;

                   b=second;

               }

           T getmax () {

                   return a>b? a : b;

           }

};

int main () {
       mypair <int> myobject (100, 75);

       cout << myobject.getmax();

       return 0;

}


一个实践比如


我将经过一个实践的比如来引导你如何将c/c++库集成到Objective-C代码中。一个比如是集成SQLite库,另一个比如是讲c++和Objective-C代码进行混编。


SQLite


SQLite是CoreData的底层完成。SQLite功用仍是不错的,由于比较轻量级和愈加直接。可是,CoreData在这些办法供给了更好的支撑:模型目标匹配,undo和redo功用,批量操作,线程。


运用SQLite的最大优点是:假如你的团队现已很熟悉相关的数据库和SQL,学习的曲线也对错常轻量级的。SQLite相同很简单移植到Android中,这样比就可以在iPhone和Android运用同享相同的数据了。


你可以阅览SQLiteSample工程的源代码。这儿我只给你一些重要的提示。


你需求翻开指令行,然后书输入sqlite3 students.sql 来创立数据库。这会创立一个新的数据库,然后就可以在这个数据库中创立表,刺进和查询数据。你可以运用SQL句子创立表和刺进数据。


sqlite> CREATE TABLE students (pk INTEGER PRIMARY KEY, name VARCHAR(25));

sqlite> INSERT INTO students (name) VALUES ('khang');
sqlite> INSERT INTO students (name) VALUES ('vo');
sqlite> INSERT INTO students (name) VALUES ('duy');

sqlite> .quit


图9-5愈加清楚的展现了在指令行中发作的工作。


你可以在Home文件夹(这个是默许的文件夹,假如你在终端操作时没有修正的话)下找到students.sql文件。你需求把这个文件增加到Xcode中,然后要增加libsqlite3.0.dylib这个库。


- (void)viewDidAppear:(BOOL)animated {
       NSString *path = [[NSBundle mainBundle] pathForResource:@"students" ofType:@"sql"];

       if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {

       // Get the primary key for all books.
       const char *sql = "SELECT pk, name FROM students";

       sqlite3_stmt *statement;

       // Preparing a statement compiles the SQL query into a byte-code program in theSQLite library.

       // The third parameter is either the length of the SQL string or -1 to read up tothe first null terminator.

       if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {

           // We "step" through the results - once for each row.
           while (sqlite3_step(statement) == SQLITE_ROW) {

                   const unsigned char *name = sqlite3_column_text(statement, 1);

                   NSString *nameString = [NSString stringWithCString:(char *)nameencoding:NSASCIIStringEncoding];

           }

       }

   // "Finalize" the statement - releases the resources associated with thestatement.

   sqlite3_finalize(statement);

} else {

       // Even though the open failed, call close to properly clean up resources.

       sqlite3_close(database);
       NSAssert1(0, @"Failed to open database with message '%s'.",

       sqlite3_errmsg(database));

}

[self.tableView reloadData];

}


这儿有一些办法你需求记住:


  • sqlite3_open([path UTF8String], &database) == SQLITE_OK 初始化和将新的数据库目标赋值给你的指针。

  • sqlite3_prepare_v2(database, sql, -1, &statement, NULL) ==SQLITE_OK  履行sql指令和把成果放入statement中。

  • while (sqlite3_step(statement) == SQLITE_ROW): 从履行的statement中遍历成果。




在你的运用中集成c++


你可以毫不费力的将c集成到你的运用中,由于Objective-C是c的超集。可是,当你在运用中集成c++的时分,你需求留意一些细节。


首要,你需求像正常相同的创立c++类的头文件和完成文件(.h和.cpp文件)。然后,你需求把包裹c++文件的Objective-C文件的后缀改为.mm(在iOS环境中这些是Objective-C++文件)。任何想要运用.mm文件的文件也有必要像a.mm这样。


你可以检查一下TestC_CPlus这个示例工程。首要,你会看到两个文件,Foo_Cpp.h 和Foo_Cpp.cpp,他们声明晰Foo_Cpp这个c++类。然后,经过MyObject.h和MyObject.m这两个Objective-c++文件进行包裹。


最终一步,把这些逻辑集成到你的view controller中。你可以在工程中像正常相同调用MyObject目标。你只需求将把调用的文件后缀改为.mm。


总结


在编程领域中,现已有许多高功用的和由特殊任务的c/c++库。你永久不需求重复创造轮子,或尽力的将c/c++代码转换成Objective-c代码。了解c/c++可以协助你更好的了解库的运用,这样你就可以把他们集成到你的运用中。


Objective-C是c的超集,所以许多c的特性你都现已知道了。我评论了c编程的一些首要的点,包含指针的概念。你也学到了函数指针,位操作,这些都是c的特性,可以很好的提高功用。


假如你没有编程经历的话,c++比较难以学习和了解。我仅仅评论了c++一些首要的知识点,c++和Objective-C的首要不同之处。关于编写一个高要求的c++程序或许信息还不行,可是关于如何将一个现已存在的c++库集成到iPhone运用中现已足够了。


在最终一部分,我运用了一个SQLite的实在的比如展现了如安在Objective-C中运用C。这个并不难,除了一些语法和内存办理上的不同。关于c++库我并没有深化评论;我仅仅展现了如何将c++代码集成到你的iPhone运用中。



版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表AG环亚娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章