2019 vc++
V C++
2007-10-28 20:37:00 asa_a 阅读数 380

    学习VC++,到CSDN来立个项。

    第三天,了解到VC和VB有很多相似处:响应消息han数,框架代码由系统生cheng,我们要做的是声明对象,创建消息响应han数、填加应用程序代码、文档代码、视窗代码,设计Resource。

    于是,目前首要任务是learn to use Function the more the better。另外,进一步熟悉VC++编程流程。第三,坚持用五笔写记录。

2015-11-17 09:26:40 mdtkzc 阅读数 273

继承与面向对象设计

这节解释C++各种不同特性的真正意义,例如“public继承”意味“is-a”,如果尝试让它带有其他意义,就会惹祸上身。virtual函数意味“接口必须被继承”,non-virtual函数意味“接口和实现都必须被继承”。

 

条款32:确定你的public继承塑模出is-a关系(Make sure public inheritance models “is-a”.

public继承”意味is-a。适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象。

 

条款33:避免遮掩继承而来的名称(Avoid hiding inherited names.

1)当位于一个derived class成员函数内指涉(refer tobase class内的某物(也许是个成员函数、typedef或成员变量)事,编译器可以找出所指涉的东西,因为derived classes继承了声明于base classes内的所有东西。实际运作方式是,derived class作用域被嵌套在base class作用域内:

 

假设derived class内的mf4的实现码部分像这样:

 

编译器查找mf2名称所指涉的东西时,首先查找local作用域(也就是mf4覆盖的作用域),没有找到任何东西名为mf2,再查找其外围作用域,也就是class Derived覆盖的作用域。还是没有找到,于是再往外围移动,本例为base class,在那儿找到了一个名为mf2的东西,于是停止查找。如果Base内还是没有mf2,查找动作便继续下去,首先找内含Base的那个namespaces)的作用域(如果有的话),最后往global作用域找。

2)C++的名称遮掩规则(name-hiding rules)所做的唯一事情就是:遮掩名称。

 

上述代码中,base class内所有名为mf1mf3的函数都被derived class内的mf1mf3函数遮掩掉了,这样的规则使用于base classesderived classes内的函数有不同的参数类型,而且不论函数是virtualnon-virtual一样适用。从名称查找观点来看,Base::mf1Base::mf3不再被Derived继承!

 

3)如何推翻C++对“继承而来的名称”的缺省遮掩行为,可以使用using声明式达成目标。

 


4)转交函数(forwarding function)。假设Derivedprivate形式继承Base,而Derived唯一想继承的mf1是那个无参数版本。

 

5)derived classes内的名称会遮掩base classes内的名称。在public继承下从来没有人希望如此。

6)为了让遮掩的名称再见天日,可使用using声明式或转交函数。

 

条款34:区分接口继承和实现继承(Differentiate between inheritance of interface and inheritance of implementation.

1)声明一个pure virtual函数的目的是为了让derived classes只继承函数接口。

2)声明简朴的(非纯)impure virtual函数的目的,是让derived classes继承该函数的接口和缺省实现。

3)声明non-virtual函数的目的是为了令derived classes继承函数的接口及一份强制性实现。

 

条款35:考虑virtual函数以外的其他选择(Consider alternatives to virtual functions.

1)借由Non-virtual interface手法实现Template Method模式

这个流派主张virtual函数应该几乎总是private。保留healthValuepublic成员函数,但让它成为non-virtual,并调用一个private virtual函数(例如doHealthValue)进行实际工作:

 

这一基本设计,也就是“令客户通过public non-virtual成员函数调用private virtual函数”,称为non-virtual interfaceNVI)手法。它是所谓Template Methond设计模式(与C++ templates并无关联)的一个独特表现形式。把这个non-virtual函数(healthValue)称为virtual函数的外覆器(wrapper)。

NVI手法的一个优点隐身在上述代码注释“做一些事前工作”和“做一些事后工作”之中。

NVI手法涉及在derived classes内重新定义private virtual函数。

2)借由Function Pointers实现Strategy模式

这个设计主张“人物健康指数的计算与人物类型无关”,例如我们可能会要求每个人物的构造函数接受一个指针,指向一个健康计算函数,而我们可以调用该函数进行实际计算:

 

这个做法是常见的Strategy设计模式的简单应用,它提供了某些有趣弹性:

(1)同一人物类型之不同实体可以有不同的健康计算函数。如:

 

(2)某已知人物之健康指数计算函数可在运行期变更。例如GameCharacter可提供一个成员函数setHealthCalculator,用来替换当前的健康指数计算函数。

3)借由tr1::function完成Strategy模式

 


std::tr1::function<int (const GameCharater&)>的目标签名式代表的函数是“接受一个reference指向const GameCharater,并返回int”。这个tr1::function类型(也就是我们所定义的HealthCalcFunc类型)产生的对象可以持有任何与此签名式兼容的可调用物(callable entity)。所谓兼容,意思是这个可调用物的参数可被隐式转换为const GameCharacter&,而其返回类型可被隐式转换为int

 

 

 

“_1”意味“当为ebg2调用GameLevel::health时是以currentLevel作为GameLevel对象”。

若以tr1::function替换函数指针,将因此允许客户在计算人物健康指数时使用任何兼容的可调用物(callable entity)。

4)古典的Strategy模式

传统(典型)的Strategy做法会将健康计算函数做成一个分离的继承体系中的virtual成员函数。设计结果如下图所示:

 

 

5)将机能从成员函数一到class外部函数,带来的一个缺点是,非成员函数无法访问classnon-public成员。

 

条款36:绝不重新定义继承而来的non-virtual函数(Never redefine an inherited non-virtual function.

1)non-virtual函数如B::mfD::mf都是静态绑定(staticallly bound)。这意思是,由于pB被声明为一个pointer-to-B,通过pB调用的non-virtual函数永远是B所定义的版本,即使pB指向一个类型为“B派生之class”的对象。

 

 

virtual函数却是动态绑定(dynamically bound),如果mf是个virtual函数,不论是通过pBpD调用mf,都会导致调用D::mf,因为pBpD真正指的都是一个类型为D的对象。

 

条款37:绝不重新定义继承而来的缺省参数值(Never redefine a function’s inherited default parameter value.

1)virtual函数是动态绑定,而缺省参数却是静态绑定。意思是你可能会在“调用一个定义于derived class内的virtual函数”的同时,却使用base class为它所指定的缺省参数值。对象的所谓静态类型(static type),就是它在程序中被声明时所采用的类型。考虑以下的class继承体系:

 

 

 

对象的所谓动态类型(dynamic type)则是指“目前所指对象的类型”。

 

此例之中,pr的动态类型是Rectangle*,所以调用的是Rectanglevirtual函数。Rectangle::draw函数的缺省参数值应该是GREEN,但由于pr的静态类型是Shape*,所以此一调用的缺省参数值来自Shape class而非Rectangle class

2)为什么C++坚持以这种乖张的方式运作呢?答案在于运行期效率。如果缺省参数值是动态绑定,编译器就必须有某种办法在运行期为virtual函数决定适当的参数缺省值,这比目前实行的“在编译期决定”的机制更慢而且更复杂。

 

条款38:通过复合塑模出has-a或“根据某物实现出”(Model “has-a” or “is-implemented-in-terms-of” through composition.

复合(composition)是类型之间的一种关系,当某种类型的对象内含它种类型的对象,便是这种关系。复合意味has-a(有一个)或is-implemented-in-terms-of(根据某物实现出)。

is-implemented-in-terms-of的一个实例:

 

 

Set对象根据一个list对象实现出来。

 

条款39:明智而审慎地使用private继承(Use private inheritance judiciously.

1)private继承的首要规则:

(1)如果classes之间的继承关系是private,编译器不会自动将一个derived class对象转换为一个base class对象。

(2)由private base class继承而来的所有成员,在derived class中都会变成private属性,纵使它们在base class中原本是protectedpublic属性。

2)private继承意味implemented-in-terms-of(根据某物实现出)。private继承纯粹只是一种实现技术。private继承意味只有实现部分被继承,接口部分应略去。如果Dprivate形式继承B,意思是D对象根据B对象实现而得,再没有其他意涵了。

3)尽可能使用复合,必要时才使用private继承。

4)EBOempty base optimization:空白基类最优化)。

 

 

在大多数编译器中sizeofEmpty)获得1,在上述情况下几乎可以确定sizeofHoldsAnInt==sizeofint)。

和复合不同,private继承可以造成empty base最优化。这对致力于“对象尺寸最小化”的程序库开发者而言,可能很重要。

5)当面对“并不存在is-a关系”的两个classes,其中一个需要访问另一个的protected成员,或需要重新定义其一或多个virtual函数,private继承极有可能成为正统设计策略。

 

条款40:明智而审慎地使用多重继承(Use multiple inheritance judiciously.

1)多重继承(multiple inheritanceMI)引起的歧义。

 

此例之中对checkOut的调用是歧义的,即使两个函数之中只有一个可取用(BorrowaleItem内的checkOutpublicElectronicGadget内的却是private)。C++解析重载函数调用的规则:在看到是否有个函数可取用之前,C++首先确认这个函数对此调用而言是最佳匹配。

解决歧义的方案:指出想要调用哪一个base class内的函数。

 

2)virtual继承

 

(1)使用virtual继承的那些classes所产生的对象往往比使用non-virtual继承的兄弟们体积大,访问virtual base classes的成员变量时,也比访问non-virtual base classes的成员变量速度慢。

(2)virtual base的初始化责任由继承体系中的最底层(most derivedclass负责,这暗示【1classes若派生自virtual bases而需要初始化,必须认知其virtual bases——不论那些basees距离多远;【2】当一个新的derived class加入继承体系中,它必须承担其virtual bases(不论直接或间接)的初始化责任。

(3)virtual继承的忠告:【1】非必要不使用virtual bases;【2】如果必须使用virtual base classes,尽可能避免在其中放置数据。

多重继承的确有正当用途。其中一个情节涉及“public继承某个Interface class”和“private继承某个协助实现的class”的两相组合。

2018-03-05 18:22:55 qq_39587172 阅读数 141

题目简介:

 

Problem Description

有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。

 

 

Input

输入数据包含多个测试实例,每组数据由两行组成,第一行是n和m,第二行是已经有序的n个数的数列。n和m同时为0标示输入数据的结束,本行不做处理。

 

 

Output

对于每个测试实例,输出插入新的元素后的数列。

 

 

Sample Input


 

3 3 1 2 4 0 0

 

 

Sample Output


 

1 2 3 4

AC代码如下

#include<iostream>
using namespace std;
int main()
{
	int n, m, t,a=0;
	while (cin >> n >> m) {
		if (n == 0 && m == 0)
			break;
		for (int i = 0; i<n; i++) {
			cin >> t;
			if (t > m&&a==0) {
				cout << m << " ";
				a = 1;
			}	
			cout << t;
			if (i != n - 1)
				cout << " ";
			else
				if (t <= m)
					cout <<" "<< m;
		}
		cout << endl;
		a = 0;
	}
}

 

2019-04-26 08:30:52 weixin_41274723 阅读数 28

Problem Description
有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。
Input
输入数据包含多个测试实例,每组数据由两行组成,第一行是n和m,第二行是已经有序的n个数的数列。n和m同时为0标示输入数据的结束,本行不做处理。
Output
对于每个测试实例,输出插入新的元素后的数列。
Sample Input
3 3
1 2 4
0 0
Sample Output
1 2 3 4

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
int main()
{
	int n, m, a;
	int num[101];
	while (cin >> n >> m)
	{
		if (n == 0 && m == 0)
		{
			break;
		}
		else
		{
			for (int i = 0; i < n; i++)
			{
				cin >> num[i];
				if (m >= num[i])
				{
					a = i + 1;
				}
			}
			for (int i = n; i >= a; i--)
			{
				num[i] = num[i - 1];
				if (i == a)
				{
					num[i] = m;
				}
			}
		}
		for (int i = 0; i <= n-1; i++)
		{
			cout << num[i] << " ";
		}
		cout << num[n] << endl;
	}
}

2012-03-24 23:54:23 fkanf 阅读数 874

      这章后面部分C++ Primer Plus带过意思,讲得不太详细。可能这部分重要吧。不过我,很多结论都是上网资料自己验证得出,时间当然不少……

 

2012-3-24(Reusing Code in C++ part V)

15. Template Versatility

We can apply the same technique to template classes as we do to regular classes. Template classes can serve as base classes, and they can be component classes. They can themselves be type argument to other templates. For example

template <typename T>
class ExDArray: public DArray<T> //inheritance
{/*class declaration*/};

template <typename T>
class Stack                                //use template class as component
{
private:
    DArray<T> items;
    int top;
// other section
};

NArray<DArray<int>,10> mix;    //nested templates 
I. Using More Than One Type Parameter

You can have a template with more than one type parameter. For example:

template <typename T1,typename T2>
class Exm
{	
private:
          T1 a;
          T2 b;
          //other portion
};

The rest of class declaration is similar to template class with single parameter.

II. Default Type Template Parameter

We can provide default values for type parameter:

                           template <typename T1,typenameT2 = int>

                           class Exm{…};

Then the declaration:

                           Exm<double> e1

is equivalent to

                           Exm<double,int> e2

If your template class has only one parameter,like:

                           template <typename T = int>

                           classDArray {…};

can also use this feature:

                           DArray<> d;  //equals toDArray<int> d

Note that we can provide default values for class template type parameters, while function template parameters can't do so.However, we can provide default values for non-type parameters for both class and function templates.

 

16. Template Specialization

Class templates are like function templates in that we can have implicit instantiations, explicit instantiations and explicit specializations, collectively known as specializations. Learning this part we can review the specialization of template functions.

I. Implicit Instantiation.

If we declare one or more objects indicating the desired type, the compiler will generate a specialized class definition, using the recipe provided by the general template. This procedure is called implicitin stantiation. The compiler doesn't generate an implicit instantiation of the class until it needs an object:

//a DArray<int> type pointer, no object needed yet 
DArray<int>* d;	
d = new DArray<int>(5);	  //an object is needed
II. Explicit Instantiation

The compiler generates an explicit instantiationof class declaration when you declare a class by using keyword template and indicating the desired type or types. The declaration should be in the same namespace as the template definition. For example, if we define a template class in a header file (in thestd namespace), we can't declare explicit instantiations in other namespace, such as in the main function.

The following statement         

             template class NArray<int,20>; //generate NArray<int,20> class

the compiler will generates the class definition,including method definition, even though no object of the class has yet been created or mentioned.

III. Explicit Specializations

Explicit specializations can be useful if you need to modify a template to behave differently when instantiated for a particular type. For example, if we want the DArray<double> class has average() const function to compute the average of all elements:

template <> class DArray<double>
{
public:
	double average() const;
	//omitted portion
};

We can regarded this class (DArray<double>) as an overloading version of DArray<double>that generated by template. So that the omitted portion can be totally different from or the same as general one. 

After declaring the explicit specialization,requesting for a DArray template of double will use this specialized definition instead of the more general template definition:

                DArray<int> d1;    //use general definition

                DArray<double> d2;  //use specialized definition

IV. Partial Specializations

C++ allows for partial specializations:

                template <typenameT1>  //specialization with T2 set to int

                class Exm<T1,int> {…};

Particularly, specifying all types leads to anempty bracket pair and a complete explicit specialization:

                template <> class Exm<int,int>{…};

The compiler uses the most specialized template:

Exm<double, double> e2;  //use the general Exm template
Exm<double, int> e2;          //use Exm<T1, int> 
Exm<int, int> e3;                  //use Exm<int, int> 

17. Member Template

A template can be a member of structure, class, or template class. So we can use templates as follows (copy from C++ Primer Plus 5th Edition ):

// tempmemb.cpp -- template members
#include <iostream>
using std::cout;
using std::endl;

template <typename T>
class beta
{
private:
    template <typename V>  // nested template class member
    class hold
    {
    private:
        V val;
    public:
        hold(V v  = 0) : val(v) {}
        void show() const { cout << val << endl; }
        V Value() const { return val; }
    };
    hold<T> q;             // template object
    hold<int> n;           // template object
public:
    beta( T t, int i) : q(t), n(i) {}
    template<typename U>   // template method
    U blab(U u, T t) { return (n.Value() + q.Value()) * u / t; }
    void Show() const { q.show(); n.show();}
};

int main()
{
    beta<double> guy(3.5, 3);

    guy.Show();
    cout << guy.blab(10, 2.3) << endl;
    cout << "Done\n";
    return 0; 
}
We need to pay attention to the member template function blab(). This program's output is 

            3.5 

          3

          28 

          Done

This indicates that U is set to type int. If we replace 10 with 10.0, the output will change:

             3.5

          3

          28.2609

           Done 

Because U is set to type double.

Unlike the first parameter, the type of the second parameter is not set by the function call. That is to say,guy.blab(10,3) would still implement blab() as blab(int, double).

 

17. Template Classes and Friends

Before we discuss about this complex portion, we have better recall the key point of friend function:

  • Friends are only ordinary functions but can access private members.
  • Friends do not belong to class(not its member function).

Next to business. We can classify friends of templates into 3 categories:

  • Non-template friends
  • Bound template friends, meaning the type of the friends is determined by the type of the class when a class is instantiated.
  • Unbound template friends, meaning that all specializations of the friends are friends to each specialization of the class.

I. Non-Template Friends

Just as its name implies, friends themselves are not template functions. But their can either have template class object parameters or not. So non-template friends have two kinds of form. For instance:       

template <typename T>
class Exm1
{
        friend void f1();	//Form I:no object parameter
        //Form II: has template class parameter
        friend void f2(Exm1<T> e);
        //… …omitted portion
};
Two kinds of non-template friends are friend to all classes generated by template class. However, in this example, we have only one f1(), so f1()can only access limited private members of the classes generated by template when typing its function body. 

Note that f2()is not itself a template function; it just has a parameter that is template. That is means that we have to define explicit specializations for the friends we plan to use. This is a kink of overloading:

       void f2(Exm1<int> e) {…}   //friend for class Exm1<int>

       void f2(Exm1<double> e){…} //friend for class Exm1<double>

Here is an example:

#include <iostream>

using namespace std;

template <typename T>
class Exm1
{
private:
    T item;
    static int obCounter;
public:
    Exm1(const T& t): item(t) {obCounter++; }
    ~Exm1(){obCounter--; }
    friend void counts();
    friend ostream& operator <<(ostream& os,const Exm1<T>& e);
};

template <typename T> int Exm1<T>::obCounter = 0;

void counts() 
{
    cout << "Number of Exm1<int> objects:" 
        << Exm1<int>::obCounter << endl;
}

ostream& operator << (ostream& os,const Exm1<int>& e)
{
    os << e.item;
    return os;
}

int main()
{
   Exm1<int> ie1(10);
   Exm1<int> ie2(20);
   Exm1<double> de(5.5);
   counts();
   cout << "Value of private member: "
       << ie1 << " " << ie2 << endl; 
   //cout << de << endl;
}
output:

              Number of Exm1<int>objects:2

              Value of private member: 10 20

counts()can access all obCounter of classes generated by template, but in this example it use Exm1<int>::obCounter. The comment line is invalid, because we have not defined the friend of  Exm1<double> yet.

II. Bound Template Friends

As we can see, non-template friends can not befriend to all classes generated by template(so operator <<()can't apply to all class objects). So we need to use a new technique to generate friends for each instantiation. That is bound template friends. The key of this technique is set class templates' type to the type of friends

Here is an example:

#include <iostream>

using namespace std;

template <typename FT> int counts();

template <typename CT>
class Exm2
{
private:
    CT item;
    static int obCounter;
public:
    Exm2(const CT& t): item(t) {obCounter++; }
    ~Exm2(){obCounter--; }
    friend int counts<CT>();	//explicit instantiation
    friend ostream& operator <<(ostream& os,const Exm2<CT>& e)
    {return (os << e.item); }
};

template <typename T> int Exm2<T>::obCounter = 0;

template <typename FT> 
int counts() 
{
    return Exm2<FT>::obCounter;
}

int main()
{

   Exm2<int> ie1(10);
   Exm2<int> ie2(20);
   Exm2<double> de(5.5);
   cout << "Objects of Exm2<int>: " << counts<int>() << endl;
   cout << "Objects of Exm2<double>: " << counts<double>() << endl;
   cout << "Value of private member: \n";
   cout << "Exm2<int>: " << ie1 << " " << ie2 << endl; 
   cout << "Exm2<double>: " << de << endl;   
}
output:

              Objects of Exm2<int>: 2

              Objects of Exm2<double>: 1

              Value of private member:

              Exm2<int>:10 20

              Exm2<double>:5.5

This program seems a little strange, but it runs well. We have two main methods to make this technique possible:

  •  Declare and define a template function, friend is the explicit instantiation of it.
  • Declare a template friend function, define it inside or outside the template class.

First of all, we can wipe out the impossible one:declare a template friend function and define it outside the template class. Because what your declare and define are different template functions. For example:

What your declare is:

           friend ostream& operator<<(ostream& os,constExm2<CT>& e)

and what your define is

template <typename FT>
ostream& operator << (ostream& os, const Exm2<FT>& e)
{/*function body*/}
The form of latter is actually a template definition, which is independent of the former. When compiler generates declaration, no one set class type(CT) to function(FT) type.

i.counts()

This friend function has no symbol to distinguish,for example, between countd()belong to Exm2<int> and counts()belong to Exm2<double>. So, the first method is the only approach.

ii. operator <<()

We choose the second way in this example, the first one is suitable for operator<()? The answer is no. The reason is ambiguous: 

template <typename FT>	//oridinary template function
ostream& operator <<(ostream& os, const FT& e)
{/*function body*/}

//explicit instantiation set Exm2<CT> to FT
friend ostream& operator << <>(ostream& os,const Exm2<CT>& e);
When the program attempt to print a string:

             cout <<"string"//invokeoperator <<(cout,"string")

operator <<(cout,"string") can match operatoe <<(ostream&,string&)(set FT to string) and operator<< in standard library.

So, declare and define friend inside the class is the only choice.

III. Unbound Template Friend

By declaring a template inside a class ,we can create unbound friend functions for which every function specialization is a friend to every class specialization:

(copy from C++ Primer Plus 5th Edition)

// manyfrnd.cpp -- unbound template friend to a template class
#include <iostream>
using std::cout;
using std::endl;

template <typename T>
class ManyFriend
{
private:
    T item;
public:
    ManyFriend(const T & i) : item(i) {}
    template <typename C, typename D> friend void show2(C &, D &);
};

template <typename C, typename D> void show2(C & c, D & d)
{
    cout << c.item << ", " << d.item << endl;
}

int main()
{
    ManyFriend<int> hfi1(10);
    ManyFriend<int> hfi2(20);
    ManyFriend<double> hfdb(10.5);
    cout << "hfi1, hfi2: ";
    show2(hfi1, hfi2);
    cout << "hfdb, hfi2: ";
    show2(hfdb, hfi2);

    return 0;
}

Output

                       hfi1, hfi2: 10,2

                       hfdb,hfi2: 10.5, 20




c++ 学籍管理系统v 1.0

阅读数 1787

#include#include#includeusingnamespacestd;classsj{public:intyear,month,day;voidshuru(){cin>>year>>month>>day;}};classstudent{public: stringxm,kc[5]; intbj,xh,cj[5]; sjtime;

博文 来自: u013102172

C++\V动态创建和释放二维数组

阅读数 980

动态创建和释放二维数组C动态创建和释放二维数组12345678910111213141516171819#include#include #defineR

博文 来自: yeluoyunfei

C++基础语法知识点归纳V

阅读数 539

Code:#include  #include  //文件读写头文件  #include  //exit()要用到的头文件   using namespace std;      /////////// 该程序要求用户输入望远镜物镜和一些目镜的焦距,然后计算并显示每个目镜的放大倍数/////

博文 来自: sarah_jieyu

C++ hdoj 2019 数列有序

阅读数 383

#includeusingnamespacestd;intmain(){intn,m,i,j=0,t;inta[120];while(cin>>n>>m){if(n==0&&m==0)break;for(i=0;in;i++){cin>>a[i];if(m>a[i]){j++;}}fo

博文 来自: xunfengdumo

C++ error LNK 2019

阅读数 324

errorLNK2019:无法解释的外部符号解决方案

博文 来自: liu1152239
没有更多推荐了,返回首页