继承的特性丰富了c++的使用,当然也有一定的使用门槛,现在简单介绍一点 这方面的知识,以备将来使用。
下面的程序代码是一个最简单的使用继承的案例,我们来看一下:
class Triangle{
public:
void triangle(){
cout<<"I am a triangle\n";
}
};
class Isosceles : public Triangle{
public:
void isosceles(){ // 等腰 三角形
cout<<"I am an isosceles triangle\n";
}
//Write your code here.
};
int main(){
Isosceles isc;
isc.isosceles();
isc.description();
isc.triangle();
return 0;
这一个是使用子类的实例化对象,继承了父类的方法。注意,这里没有解释一
些细节的问题,比如说public的属性什么的,只是在感官层面上进行一个概
括。
当然,还可以继续继承下去.
class Equilateral : public Isosceles{
public:
void equilateral(){
cout << "I am an equilateral triangle\n";
}
};//Write your code here.
// 使用的话 ,可以直接实例化 Equilateral
int main(){
Equilateral eqr;
eqr.equilateral();
eqr.isosceles();
eqr.triangle();
return 0;
}
其实这里面对有关权限的制约还是非常复杂的,我这里暂时不打算讲述这些,毕竟我自己没有 尝试这些东西,那就先整下自己已经涉及到的内容。
这是什么意思?比如说,我的父类中有一个方法display (),这个方法就是用来展示父类内部
的成员变量,但是呢,父类不提供构造方法,而是通过子类去给父类的成员变量赋值,这听起
来很变态,但是,这是hackeranker的一道题目
技巧在于在子类中使用keyword using,这个时候,你在子类中父类的变量(这个变量必须设置
为 public)在子类中就可以自由的使用了.
#include <iostream>
using namespace std;
/*
* Create classes Rectangle and RectangleArea
*/
class Rectangle{
public:
int width;
int height;
public:
void display(){
cout << width << " " << height << endl;
}
};
class RectangleArea : public Rectangle {
public:
using Rectangle::width; // 直接调用父类的成员
using Rectangle::height;
public:
void read_input(){
cin >> width >> height;
}
void display(){
cout << width * height << endl;
}
};
int main()
{
RectangleArea r_area;
r_area.read_input();
/*
* Print the width and height
*/
r_area.Rectangle::display();
/*
* Print the area
*/
r_area.display();
return 0;
}
对于这个方案的处理,我不知道还有没有更好的处理呢?
简单一句话就是,google打算使用soong代替庞大的mk文件群,从而让aosp的开发更方便一些.
使用这个工具可以将mk文件中的变量、模块、评论或者一些其他的条件转化为Android.bp文件,比较复杂的
需要手工转换。
androidmk Android.mk > Android.bp
mk文件和bp文件的差别在于,mk文件可以允许有相同名字的多个模块,但是bp文件就不能这样,但是后者可以有 多个变量。
整体的build逻辑使用GO的blueprint编写。所有的build 规则被bp文件搜集并且写入ninja build 文件。
流程:
上面的流程有待确定
Blueprint更像是一个库,专门来翻译blueprint文件,关于Blueprint文件格式可以参考build/blueprint/Blueprints文件,soong是在blueprint上面的扩展,基于blueprint的语法定制产生Android.bp语法,解析Android.bp文件生成ninja文件。 来源 jianshu
着四者之间的关系你看看下面的build目录就行了.
从aosp 7.0开始,aosp在prebuilts/go/目录下新增go语言的运行环境就是为了他们之间的转换。
kati就是上文所说的 androidmk的工具,源码位于:
user@host037-ubuntu-1804:~/zhimo-aosp/build$ ls
blueprint buildspec.mk.default CleanSpec.mk core envsetup.sh kati make soong target tools
kati下面的内容也是巨多,看来就是实现了一个虚拟机的功能(或者需要编译原理),这个门槛怎么也绕不过去。根据他内部的文档,kati也是一个短期的项目.
目前,kati的主要 mode是 ninjamode.(build.ninja)
下面我翻译一下谷歌的官方文档:
...相反通过他自己执行build命令,kati产生`build.ninja`文件去执行上述命令。kati目前的形式是多次试验的结果,一些实验成功了,然而另外一些实验却失败了。我们甚至改变语言。期初,我们使用go编写的kati,我们天真的期待着在编译性能上有足够的提升。至少,我们可以得出三个结论...其实,谷歌自己也在为go的性能担心,当然,这不是这篇文章的核心,我们的目前是如何快速的编译出aosp系统,而不是讨论哪种方法更好,c的效率足够高,但是GNU的Makefile内容太臃肿. test
std::ostream& operator << (std::ostream& out, Box& B){
out << B.getLength() << " " << B.getBreadth() << " " << B.getHeight();
return out;
}
this is “«” overload. Note it will be defined at beside of class.
bool operator < (const Box& B){ // overload operator "<"
if (this->l < B.l)
return true;
else if (this->l == B.l && this->b < B.b)
return true;
else if (this->l == B.l && this->b == B.b && this->h < B.h)
return true;
else
return false;
};
This is <’s override,which is defined in class,Why it is different from
above example.Yes, the reason that is we can use keyword this pointer to
access private numbers of class.
c++的智能指针可以说是一个高级用法,尤其是在大型项目中,一定少不了这个东西的参与。 也许,你不必亲自探究它的源码构成,但是看一看它是如何工作的,对自己的c++基础还有有莫大的帮助。
所有的智能指针头文件是memory.智能指针的意图是解决内存管理的问题,如果你使用了智能指针去
申请内存,可以放心地保证减少内存泄漏的问题的产生。
首先看一下自己如何实现自动删除资源的class:
class smartPtr{
int *ptr; // actual pointer
public:
explicit smartPtr(int *p = NULL) { ptr = p; } // constructor
~smartPtr() { delete(ptr); }
int& operator *() { return *ptr; }
};
int main()
{
smartPtr ptr(new int());
*ptr = 20;
cout << *ptr << endl;
return 0;
}
这里有一些东西有待确证,实例化的对象是不是在程序退出后、也就是obj的生命周期结束后
自动调用析构函数,而且,你看,在类中还重载了\*符号。
std::auto_ptr
这个指针类已经被丢弃了,能不用这个就不用它吧。显而易见,推荐使用unique_ptr
这个问题也需要总结一下,因为最明显的方案有两种。孰好孰坏,还得看情况。 题目来自于hackerrank
这个在开源代码里比较常见,据说效率上比较快的。因为是构造函数吗,这里就涉及到
多参函数和无参函数。请看以下代码,是初始化一个Box()中的长宽高(l,b,h).
class Box{
private:
int l, b, h;
public:
Box() : l(0), b(0), h(0){}
Box(int length, int breath, int height) :
l(length),b(breath),h(height) // be carefully ","
{
} // this is initialzer list method
Box (const Box& obj) :
l(obj.l), b(obj.b),h(obj.h)
{} // copy constructor
int getLength() {
return this->l;
}
int getBreadth() {
return this->b;
}
int getHeight() {
return this->h;
}
long long int CalculateVolume() // 必须大数梳理
{
long long int result = 1LL * this->l * this->b * this->h;
return result;
}
};
Please note the initialized list model is :
Box(int length, int breath, int height) :
l(length),b(breath),h(height) // be carefully ","
{
} // this is initialzer list method
There is copy constructor function Box(const Box& obj)
The fundamental principle of copy constructor i dont understand.But we first
have a glance at :
Box(int length, int breath, int height):l(length),b(breathr, h(height) {}
and l,b,h is private variables that we want to pass constructor
function’s arguments.
Notes: There will be must use initialized list as below:
class Box() {
private:
int m_length;
int m_height;
public:
Box(int length, int height) : m_length(length),m_height(height){}
} // below must use it ^_^
class red_Box: public Box{
public:
red_Box(int length, int height, int type) :
Box(length, height){
;
} // must use initialized list
private:
int type;
}
class Box() {
private:
int m_length;
int m_height;
public:
Box(int length, int height) : m_length(length),m_height(height){}
} // below must use it ^_^
class red_Box: public Box{
public:
red_Box(int length, int height, int type) :
Box(length, height),
TYPE(2)
{
// if TYPE = 4 is error
} // must use initialized list
private:
int type;
const int TYPE;
```c Box(){ l = 0, b = 0, h = 0; } // default value is 0, maybe use below method
# 拷贝构造函数
```c
Box (const Box& obj) :
l(obj.l), b(obj.b),h(obj.h)
{} // copy constructor
任何一门编程语言的输入输出都应该彻底的掌握,c++更应该是这样的。
这个直接使用
int main() {
int a; long b; char c; float d; double e;
cin >> a >> b >> c >> d >>e;
cout << a << endl << b << endl << c << endl;
cout << setiosflags(ios::fixed) << setprecision(3);
cout << d << endl;
cout << setiosflags(ios::fixed) << setprecision(9);
cout << e << endl;
return 0;
}
方法setiosflags具有后效性,一旦你设置了,一直到程序结束,精确度会一直保持下去的.
有两种方式: getline()和cin.getline().
该函数可以直接读取c++的string。
string str;
getline(cin, str);
cout << str << endl;
结果:
vimer@host:~/test$ g++ -g getline.cpp -o getline
vimer@host:~/test$ ./getline
[null,2,3,null,] # input
[null,2,3,null,] # output
这是一种类似c的方式使用数组。
char str2[1024];
cin.getline(str2, 1024);
cout << str2 << endl;
结果:
vimer@host:~/test$ g++ -g getline.cpp -o getline
vimer@host:~/test$ ./getline
[2,3,,null] # input
[2,3,,null] # output
leetcode的c++代码,尤其是二叉树的那部分,其测试用例都是使用,例如:
[1, null,3,4,5]
这类的数组形式的输入,那如果自己写测试用例怎么办?我的思路是,首先按照上面的方式整行读取文本内容,然后再借助c++的 strtok函数分别提取出来或者存储在另外一个数组。