Cpp笔记(一)

const safe:

#include<iostream>
using namespace std;

class A{
	int ia;
public:
	void setA(const int a){
		ia = a;
	}
	int getA() const {
		/* const-safe functions:
		 * won't change anything;
		 * const object may only use const safe methods in the class
		 */
		cout << "this is the const getA()" << endl;
		return ia;
	}
	int getA()  {
		cout << "this is the mutable getA()" << endl;
		return ia;
	}
};
int main(){
	A a;
	a.setA(47);
	const A b = a;
	cout <<"a is " << a.getA() << endl; //prefer the mutable version
	cout <<"b is " << b.getA() << endl; //only allowed to call const version
}

a is this is the mutable getA()
47
b is this is the const getA()
47


Namespace and class to basic types

#include<iostream>

namespace BWString{

const std::string bws = "This is BWString::string";
class string{
	std::string s;
public:
	string (void) : s(bws) {};
	string (const std::string & s) : s(bws) {};
	operator std::string & (void) {return s;}
	/*operator Type(void) {
	 	 ......
	 	 return TypeValue;
	 } 
	 */
};
}
BWString::string s1("This is a string");

int main(int args, char** argv){
	std::string s=s1;
	std::cout<< s << std::endl;
	return 0;
}
This is BWString::string

Explicit vs Implicit Conversion:

#include<iostream>

class Rational{
	int _n;
	int _d;
public:
	Rational(int numerator=0, int denominator=1):_n(numerator), _d(denominator){
		std::cout << "parameter constructor" << std::endl;
	};
	Rational(const Rational & rhs):_n(rhs._n), _d(rhs._d) {
		std::cout << "copy constructor" << std::endl;
	};
	~Rational();
	inline int numerator() const {return _n;}
	inline int denominator() const {return _d;}
	Rational & operator = (const Rational & rhs) ;
	Rational operator + (const Rational & rhs) const;
};
Rational & Rational::operator = (const Rational & rhs){
	if(this != &rhs){
		std::cout << "assignment" << std::endl;
		_n = rhs._n;
		_d = rhs._d;
	}
	return *this;
}
Rational Rational::operator + (const Rational & rhs) const{
	return Rational(_n*rhs._d + _d*rhs._n, _d*rhs._d);
}
Rational::~Rational(){
	std::cout << "destructor: " << _n << "/" << _d << std::endl;
}
std::ostream & operator << (std::ostream & o, const Rational & rhs){
	return o << rhs.numerator() << "/" << rhs.denominator();           //
}
int main(int args, char** argv){
	using namespace std;

	Rational a = 7;  //parameter constructor
	cout << "a is: " << a << endl;

	return 0;
}
OUTPUT:

parameter constructor

a is: 7/1

destructor: 7/1

#include<iostream>

class Rational{
	int _n;
	int _d;
public:
	explicit Rational(int numerator=0, int denominator=1):_n(numerator), _d(denominator){
		std::cout << "parameter constructor" << std::endl;
	};
	Rational(const Rational & rhs):_n(rhs._n), _d(rhs._d) {
		std::cout << "copy constructor" << std::endl;
	};
	~Rational();
	inline int numerator() const {return _n;}
	inline int denominator() const {return _d;}
	Rational & operator = (const Rational & rhs) ;
	Rational operator + (const Rational & rhs) const;
};
Rational & Rational::operator = (const Rational & rhs){
	if(this != &rhs){
		std::cout << "assignment" << std::endl;
		_n = rhs._n;
		_d = rhs._d;
	}
	return *this;
}
Rational Rational::operator + (const Rational & rhs) const{
	return Rational(_n*rhs._d + _d*rhs._n, _d*rhs._d);
}
Rational::~Rational(){
	std::cout << "destructor: " << _n << "/" << _d << std::endl;
}
std::ostream & operator << (std::ostream & o, const Rational & rhs){
	return o << rhs.numerator() << "/" << rhs.denominator();           //
}
int main(int args, char** argv){
	using namespace std;

	//Rational a = Rational(7);  //parameter constructor
	Rational a(7);
	cout << "a is: " << a << endl;

	return 0;
}

OUTPUT:

parameter constructor

a is: 7/1

destructor: 7/1


#include<iostream>

const std::size_t maxlen = 1024;

class BWSize{
	std::size_t _size;
public:
	explicit BWSize(const std::size_t);
	explicit BWSize(const char *);
	std::size_t size() const;
};
BWSize::BWSize(const std::size_t n){
	std::cout << "BWSize from int" << std::endl;
	_size = n <= maxlen ? n:0;
}
BWSize::BWSize(const char* s){
	std::cout << "constructor: BWSize from c-string" << std::endl;
	for(std::size_t i=0; i < maxlen; i++){
		if(!s[i]){
			_size = i;
			return;
		}
	}
	_size = 0;
}
std::size_t BWSize::size() const{
	return _size;
}
using namespace std;

void func(const BWSize & s){
	cout << "s.size is " << s.size() << endl;
}
int main(){
	//BWSize s = 'x'; implicit conversion
	//BWSize s = (size_t) 120; doesn't work; we have parameterized constructor not copy constructor
	BWSize s((size_t)125);
	cout << "s.size is " << s.size() << endl;
	//func('x'); implicit conversion
	func(BWSize("xxxxx"));
	return 0;
}
BWSize from int
s.size is 125
constructor: BWSize from c-string
s.size is 5


__________________________________________________________________________________________________________________________________________Animal Class:

#include<iostream>
using namespace std;

const static string unk = "unknow";
const static string clone_prefix = "clone-";

class Animal{
	string _type;
	string _name;
	string _sound;
public:
	Animal();
	Animal(const string & type, const string & name, const string & sound);

	Animal(const Animal &);
	Animal & operator=(const Animal &);
	~Animal();
	void print() const;
};
Animal::Animal(): _type(unk), _name(unk), _sound(unk){
	cout << "default constructor" << endl;
}
Animal::Animal(const string & type, const string & name, const string & sound)
:_type(type), _name(name), _sound(sound){
	cout << "constructor with arguments" << endl;
}
Animal::Animal(const Animal & a){
	cout << "copy constructor" << endl;
	_type = a._type;
	_name = clone_prefix + a._name;
	_sound = a._sound;
}
Animal::~Animal(){
	cout << "destructor: "
			<< _name <<  ", the " << _type
			<<endl;
}
void Animal::print() const{
	cout << _name << ", the " << _type
			<<", says " << _sound << endl;
}
Animal & Animal::operator=(const Animal & o){                         //
	cout << "assignment operator" << endl;
	if(this != &o){
		_name = clone_prefix + o._name;
		_type = o._type;
		_sound = o._sound;
	}
	return *this;
}
int main(int args, char** argv){
	Animal a;
	a.print();

	const Animal b("goat", "bob", "baah");
	b.print();

	const Animal c = b;
	c.print();

	a = c;
	a.print();

	return 0;
}
default constructor
unknow, the unknow, says unknow
constructor with arguments
bob, the goat, says baah
copy constructor
clone-bob, the goat, says baah
assignment operator
clone-clone-bob, the goat, says baah
destructor: clone-bob, the goat
destructor: bob, the goat
destructor: clone-clone-bob, the goat

Complex class (friend function overload)

#include<iostream>
using namespace std;
class Complex{
	double _real, _image;
public:
	Complex(double r = 0, double i = 0);
	void print() const;
	friend Complex operator+(const Complex & lhs, const Complex & rhs); //overloading non-member function declared in Complex class
	friend Complex operator-(const Complex & lhs, const Complex & rhs);
	friend Complex operator-(const Complex & c);
};
Complex::Complex(double r, double i):_real(r), _image(i) {};
void Complex::print() const{
	cout << "(" << _real << "," << _image << ")" << endl;
}
Complex operator+(const Complex & rhs, const Complex & lhs){
	double r = rhs._real + lhs._real;
	double i = rhs._image + lhs._image;
	return Complex(r, i);
}
Complex operator-(const Complex & rhs, const Complex & lhs){
	double r = rhs._real - lhs._real;
	double i = rhs._image - lhs._image;
	return Complex(r, i);
}
Complex operator-(const Complex & c){;
	return Complex(-c._real, -c._image);
}
int main(){
	Complex c1(2.5, 3.7), c2(4.2, 6.5);
	Complex c;
	c = c1 - c2;
	c.print();
	c = 25 + c2;
	c.print();
	c = c2 + 25;
	c.print();
	c = -c1;
	c.print();
	return 0;
}

(-1.7,-2.8)
(29.2,6.5)
(29.2,6.5)
(-2.5,-3.7)

Rational:

#include<iostream>

class Rational{
	int _n;
	int _d;
public:
	Rational(int numerator=0, int denominator=1):_n(numerator), _d(denominator){
		//std::cout << "parameter constructor" << std::endl;
	};
	Rational(const Rational & rhs):_n(rhs._n), _d(rhs._d) {
		//std::cout << "copy constructor" << std::endl;
	};
	~Rational();
	inline int numerator() const {return _n;}
	inline int denominator() const {return _d;}
	Rational & operator = (const Rational & rhs) ;
	Rational operator - (const Rational & rhs) const;
	Rational operator * (const Rational & rhs) const;
	Rational operator / (const Rational & rhs) const;
	operator std::string (void) const;
};
Rational & Rational::operator = (const Rational & rhs){
	if(this != &rhs){
		std::cout << "assignment" << std::endl;
		_n = rhs._n;
		_d = rhs._d;
	}
	return *this;
}
Rational Rational::operator - (const Rational & rhs) const{
	return Rational(_n*rhs._d - _d*rhs._n, _d*rhs._d);
}
Rational Rational::operator * (const Rational & rhs) const{
	return Rational(_n*rhs._n, _d*rhs._d);
}
Rational Rational::operator / (const Rational & rhs) const{
	return Rational(_n*rhs._d, _d*rhs._n);
}
Rational::~Rational(){
	std::cout << "destructor: " << _n << "/" << _d << std::endl;
}
std::ostream & operator << (std::ostream & o, const Rational & rhs){
	return o << rhs.numerator() << "/" << rhs.denominator();           //
}
Rational operator + (const Rational & lhs, const Rational & rhs) {
	return Rational(lhs.numerator()*rhs.denominator() + lhs.denominator()*rhs.numerator(),
			lhs.denominator()*rhs.denominator());
}
Rational::operator std::string (void) const{
	const static int maxstring = 64;
	char s[maxstring];
	snprintf(s, maxstring, "%d/%d", _n, _d);
	return std::string(s);
}
int main(int args, char** argv){
	using namespace std;

	Rational a = 7;  //parameter constructor
	cout << "a is: " << a << endl;
	Rational b(5, 3);
	cout << "b is: " << b << endl;
	Rational c = b;
	cout << "c is: " << c << endl;
	Rational d;
	cout << "d is: " << d << endl;
	d = c;
	cout << "d is: " << d << endl;
	Rational & e = d;
	d = e;
	cout << "e is: " << e << endl;

	cout << a << " + " << b << " = " << a+b << endl;
	cout << a << " - " << b << " = " << a-b << endl;
	cout << a << " * " << b << " = " << a*b << endl;
	cout << a << " / " << b << " = " << a/b << endl;

	cout << 25 << " + " << b << " = " << 25+b << endl;

	string s = "Rational as a string: ";
	s += b;
	cout << s << endl;
	return 0;
}

a is: 7/1
b is: 5/3
c is: 5/3
d is: 0/1
assignment
d is: 5/3
e is: 5/3
7/1 + 5/3 = 26/3
destructor: 26/3
7/1 - 5/3 = 16/3
destructor: 16/3
7/1 * 5/3 = 35/3
destructor: 35/3
7/1 / 5/3 = 21/5
destructor: 21/5
25 + 5/3 = 80/3
destructor: 80/3
destructor: 25/1
Rational as a string: 5/3
destructor: 5/3
destructor: 5/3
destructor: 5/3
destructor: 7/1


new-delete

#include <iostream>
using namespace std;


class A {
	int _a;
	int _b;
	int _c;
public:
	A( int );
	~A();
	int a() { return _a; }
	int b() { return _b; }
	int c() { return _c; }
};


A::A( int i = 0 ) : _a(i), _b(i + 1), _c(i + 2) {
	cout << "A constructor called" << endl;
}


A::~A() {
	cout << "A destructor called" << endl;
}


int main( int argc, char ** argv ) {
	cout << "allocating space for one A object" << endl;
	A * a = new (nothrow) A[5];  //A * a = new (nothrow) A(5);
	if(a == nullptr) {
		cerr << "new A failed." << endl;
		return 1;
	}
	for(int i=0; i < 5; ++i){
		printf("a: %d, %d, %d\n", a[i].a(), a[i].b(), a[i].c());
	}
	delete[] a;
	cout << "space for A object deleted" << endl;
	
        //printf("a: %d, %d, %d\n", a->a(), a->b(), a->c());
//delete a;return 0;}
 allocating space for one A objectA constructor calledA constructor calledA constructor calledA constructor calledA constructor calleda: 0, 1, 2a: 0, 1, 2a: 0, 1, 2a: 0, 1, 2a: 0, 1, 2A destructor calledA destructor calledA destructor calledA destructor calledA destructor calledspace for A object deleted 

Exceptions:

#include<iostream>
#include<exception>
using namespace std;

static string unk = "unknown";
static string clone_prefix = "clone-";

class E: public exception{
	const char* msg;
	E() {};
public:
	//throw() specifies what exceptions are allowed to be thrown from inside this function
	//and the list is empty, which means it does not allow any exceptions
	//to be thrown from inside this function
	//-> exception class does not throw any exception to prevent recursion
	E(const char* s) throw(): msg(s) {};
	const char* what() const throw() { return msg; }
};
class Animal{
	string _type, _name, _sound;
public:
	Animal();
	explicit Animal(const string & type, const string & name, const string & sound);

	Animal(const Animal &);
	Animal & operator = (const Animal & rhs);
	~Animal();
	void print() const;
};
Animal:: Animal(): _type(unk), _name(unk), _sound(unk) {
	cout << "default constructor" << endl;
};
Animal:: Animal(const string & type, const string & name, const string & sound)
:_type(type), _name(name), _sound(sound) {
	if(!(type.length() && name.length() && sound.length())){
		throw E("Insufficient parameters");
	}else{
		cout << "constructor with parameters" << endl;
	}
};
Animal:: Animal(const Animal & rhs)
:_type(rhs._type), _name(rhs._name), _sound(rhs._sound) {};
Animal & Animal::operator = (const Animal & rhs){
	if(this != &rhs){
		cout << "Assignment operator" << endl;
		_type = rhs._type;
		_name = clone_prefix + rhs._name;
		_sound = rhs._sound;
	}
	return *this;
}
Animal::~Animal(){
	cout << _name << ", the " << _type << endl;
}
void Animal::print(void) const{
	cout << _name << ", the " << _type << ", says " << _sound << endl;
}
int main(){
	try{
		Animal x("bear", "bill", "");
		x.print();
	} catch(exception & e){  //exception & e
		cerr << "Animal x: " << e.what() << endl;
	}
	return 0;
}
Animal x: Insufficient parameters

__________________________________________________________________________________________________________________________________________

Class inheritance: base/super/parent class, derived/sub/child class

specifierbase classderived classother objects
public111
protected11 
private1  
derived class can add member and overload members of base class

friend declaration guarantees private member access to functions and classes

polymorphism:

generic pointer(pointer to base class) , virtual method + virtual destructor(derived class destructor overloads the destructor in base class)

multiple inheritance:

 

#include <iostream>
using namespace std;

// Base class
class Animal {
	string _name;
	string _type;
	string _sound;
	// private constructor prevents construction of base class
	Animal(){};
protected:
	// protected constructor for use by derived classes
	Animal ( const string & n, const string & t, const string & s )
		: _name(n), _type(t), _sound(s) {}
public:
	void speak() const;
	const string & name() const { return _name; }
	const string & type() const { return _type; }
	const string & sound() const { return _sound; }
};

void Animal::speak() const {
	printf("%s the %s says %s\n", _name.c_str(), _type.c_str(), _sound.c_str());
}
class Fur{
	string _type;
	Fur() {};
protected:
	Fur(const string & f): _type(f) {}
public:
	const string & type() {return _type;}
};

// Dog class - derived from Animal
class Dog : public Animal {
	int walked;
public:
	Dog( string n ) : Animal(n, "dog", "woof"), walked(0) {};
	int walk() { return ++walked; }
};

// Cat class - derived from Animal
class Cat : public Animal, public Fur {
	int petted;
public:
	Cat( string n ) : Animal(n, "cat", "meow"), Fur("silky"), petted(0) {};
	int pet() { return ++petted; }
	void grooming();
};
void Cat::grooming(){
	cout << Animal::name() << " grooms her" << Fur::type() << " fur" << endl;
}
// Pig class - derived from Animal
class Pig : public Animal {
	int fed;
public:
	Pig( string n) : Animal(n, "pig", "oink"), fed(0) {};
	int feed() { return ++fed; }
};

int main( int argc, char ** argv ) {
	Dog d("Rover");
	Cat c("Fluffy");
	Pig p("Arnold");

	d.speak();
	c.speak();
	p.speak();

	cout << d.name() << " the dog has been walked " << d.walk() << " times" << endl;
	cout << c.name() << " the cat has been petted " << c.pet() << " times" << endl;
	cout << p.name() << " the pig has been fed " << p.feed() << " times" << endl;
	c.grooming();
}

__________________________________________________________________________________________________________________________________________

generic programming

#include<iostream>
using namespace std;

template<typename Type>
Type maxof(Type a, Type b){
	return (a > b? a: b);
}
int main(){
	cout << maxof("aaaaa", "baaaa") << endl;
	cout << maxof<string>("aaaaa", "baaaa") << endl;
	return 0;
}
aaaaa
baaaa
#include<iostream>
#include<vector>
using namespace std;

//if sepT isn't specified, it will default to the value_type of the container type
template<typename cT, typename retT=cT, typename sepT=decltype(cT::value_type)>
retT joinContainer(const cT & o, const sepT & sep){
	retT out;
	auto it = o.begin();
	while(it != o.end()){
		out += *it;
		if(++it != o.end()){
			out += sep;
		}
	}
	return out;
}
int main(){
	string s1("This is a string");
	string s2("This is also a string");
	string s3("Yet another string");

	cout << joinContainer(s1, ':') << endl;

	vector<string> vs({s1, s2, s3});
	cout << joinContainer<vector<string>, string>(vs, ", ") << endl;

	return 0;
}
T:h:i:s: :i:s: :a: :s:t:r:i:n:g
This is a string, This is also a string, Yet another string
#include<iostream>
#include<exception>

class E: public std::exception{
	const char * msg;
	E() {};
public:
	explicit E(const char * s) throw(): msg(s) {}
	const char * what() const throw() { return msg; }
};
template<typename T>
class Stack{
	static const int defaultSize = 100;
	static const int maxSize = 1000;
	int _size;
	int _top;
	T * stackPtr;
public:
	explicit Stack(int s = defaultSize);
	~Stack() { delete [] stackPtr; }
	T & push(const T &);
	T & pop();
	bool isEmpty() const { return _top < 0; }
	bool isFull() const { return _top + 1 >= _size ;}
	int top() const { return _top; }
	int size() const {return _size;  }
};
template<typename T>
Stack<T>:: Stack(int s){
	if(s > maxSize || s < 1){
		throw E("Invalid stack size");
	} else{
		_size = s;
		_top = -1;
		stackPtr = new T[_size];
	}
}
template<typename T>
T & Stack<T>::push(const T & i){
	if(isFull()) { throw E("stack full"); }
	else { return stackPtr[++_top] = i; }
}
template<typename T>
T & Stack<T>::pop(){
	if(isEmpty()) { throw E("stack empty"); }
	else { return stackPtr[_top--]; }
}
int main(int argc, char ** args){
	using namespace std;
	Stack<int> si(5);
	cout << "si size: " << si.size() << endl;
	cout << "si top: " << si.top() << endl;
	si.push(1);
	si.push(2);
	si.push(3);
	si.push(4);
	si.push(5);
	cout << "si after pushes: " << si.top() << endl;
	cout << "si is " << (si.isFull()? "" : "not ") << "full" << endl;

	while(!si.isEmpty()){
		cout << "popped " << si.pop() << endl;
	}

}
si size: 5
si top: -1
si after pushes: 4
si is full
popped 5
popped 4
popped 3
popped 2
popped 1

















 


















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值