Java程序员学习C++,懂Java泛型、C++模板的异同的童鞋进来解答一下!

kosora曹 2014-03-07 11:14:36
我的需求是,想写一个泛型冒泡,来测试能否对任意class、任意策略进行排序
这是Java代码,可以运行成功:



/**
* 比较器接口
*/
interface MyComp<T>{
int compare(T t1,T t2);
}
/**
*id策略
*
*/
class IdComp implements MyComp<Person>{
@Override
public int compare(Person t1, Person t2) {
return t1.id-t2.id;
}
}
/**
* age策略
*
*/
class AgeComp implements MyComp<Person>{
@Override
public int compare(Person t1, Person t2) {
return t1.age-t2.age;
}

}
class Person{
int id;
int age;
public Person(int id, int age) {
super();
this.id = id;
this.age = age;
}
@Override
public String toString() {
return "Person [id=" + id + ", age=" + age + "]";
}

}

public class MpSort {
/**
* 交换
*/
public static <T> void swap(T[] array,int a,int b){
T temp=array[a];
array[a]=array[b];
array[b]=temp;
}
/**
* 输出array
*/
public static <T> void printArray(T[] array){
for(T t:array){
System.out.println(t);
}
}
/**
*泛型冒泡
*/
public static <T> void sort(T[] array,MyComp<T> comp){
for(int i=0;i<array.length-1;i++){
for(int j=0;j<array.length-1-i;j++){
if(comp.compare(array[j], array[j+1])>0){
swap(array, j, j+1);
}
}
}
}
public static void main(String[] args) {
Person p1=new Person(1, 3);
Person p2=new Person(2, 2);
Person p3=new Person(3, 1);
Person[] array={p2,p1,p3};
//第一次我想根据id排序
sort(array, new IdComp());
System.out.println("id升序");
printArray(array);
//第二次我想根据age排序
System.out.println("age升序");
sort(array, new AgeComp());
printArray(array);
}
}



输出:
id升序
Person [id=1, age=3]
Person [id=2, age=2]
Person [id=3, age=1]
age升序
Person [id=3, age=1]
Person [id=2, age=2]
Person [id=1, age=3]

但我用Java的思路“异想天开”的写C++的冒泡却死活编译不通过:


#include <iostream>
#include<sstream>
using namespace std;
template<typename T>
/**
* 比较器接口
*/
class MyComp{
public:
int compare(T *t1,T *t2);
};
class Person{
public:
int id;
int age;
Person(int id, int age) {
this->id = id;
this->age = age;
}
string toString(){
ostringstream oss;
oss << "{age:" << this->age<<",id:" <<this->id<< "}"<<endl;
return oss.str();
}
};
/**
*id策略
*
*/
class IdComp: virtual public MyComp<Person>{
public:
int compare(Person *t1, Person *t2) {
return t1->id-t2->id;
}
};
/**
* age策略
*
*/
class AgeComp : virtual public MyComp<Person>{
public:
int compare(Person *t1, Person *t2) {
return t1->age-t2->age;
}
};

template<typename T>
/**冒泡排序*/
class MpSort{
public:
/**
* 交换
*/
void swap(T **array,int a,int b){
T* temp=array[a];
array[a]=array[b];
array[b]=temp;
}
/**
*泛型冒泡
*/
void sort(T **array ,int n,MyComp<T> *comp){
for(int i=0;i<n-1;i++){
for(int j=0;j<n-1-i;j++){
if(comp->compare(array[j], array[j+1])>0){
swap(array, j, j+1);
}
}
}
}
};

void printArray(Person **array,int n){
for(Person **p=array;p<array+n;p++){
cout<<(*p)->toString()<<endl;
}
}
int main() {
Person *p1=new Person(1,3);
Person *p2=new Person(2,2);
Person *p3=new Person(3,1);
Person** array=new Person*[3];
array[0]=p1;
array[1]=p2;
array[2]=p3;
MpSort<Person> mpSort;
IdComp *idComp=new IdComp();
//第一次我想根据id排序
mpSort.sort(array,3, idComp);
cout<<"id升序:"<<endl;
printArray(array,3);
//第二次我想根据age排序
cout<<"age升序:"<<endl;
AgeComp *ageComp=new AgeComp();
mpSort.sort(array,3,ageComp);
printArray(array,3);
delete p1;
delete p2;
delete p3;
delete[] array;
return 0;
}


我在网上搜了好久,看到的都是“重载运算符”的冒泡,它的缺点就是不能第二次扩展;求高手贴代码给我!
...全文
314 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
dianyancao 2014-03-13
  • 打赏
  • 举报
回复
为什么不给2楼分啊?
daifei4321 2014-03-09
  • 打赏
  • 举报
回复
一方面C++本身就有这个功能。一方面Java本身也有这个功能,在java.util.Collections.sort需要比较新版的Java。 你C++的问题似乎出在继承class的时候用了virtual,试试别用。另外,C++可以直接拿函数当作参数,而不是像Java必须要拿带有函数的对象当参数,直接传递比较函数就行了.
dianyancao 2014-03-09
  • 打赏
  • 举报
回复
用C++模板则对每个比较接口都得生成一份实例化代码

捣蛋不对 2014-03-09
  • 打赏
  • 举报
回复
许久没碰过java了 楼主的需求,C++中STL完全可以满足
menzi11 2014-03-09
  • 打赏
  • 举报
回复
没有看的特仔细,但楼主二楼出现的错误,应该如此做就可以了:

class MyComp{
public:
    virtual int compare(T *t1,T *t2)=0;
};
原因在于你不加virtual的话子类的同名的函数不会自动实现多态,跟java不是一个意思. 另外不得不感叹一下java程序员和C++程序员的区别,细微的语法和理念区别直接影响了 程序员的行为,我从学C++那天起就真的从没想过用虚函数做比较器. 还有楼主,你内存泄露了....... 用C++实现的话,这样就很方便:

.............

class Person
{
public:
	int id;
	int age;
	 Person(int id, int age).....
	string toString().......
};

template<typename T>
/**冒泡排序*/
class MpSort{
public:
    void swap(T **array,int a,int b)......
    template<typename Fun>
    void sort(T **array ,int n,const Fun& fun)
    {
       for(int i=0;i<n-1;i++){
	   for(int j=0;j<n-1-i;j++){
	       if(fun(array[j], array[j+1])>0){
	           swap(array, j, j+1);
	       }
	   }
       }
    }
};

void printArray(Person **array,int n)...........

int main() {
	Person *p1=new Person(1,3);
	Person *p2=new Person(2,2);
	Person *p3=new Person(3,1);
	Person** array=new Person*[3];
	array[0]=p1;
	array[1]=p2;
	array[2]=p3;
	MpSort<Person> mpSort;
	IdComp *idComp=new IdComp();
	//第一次我想根据id排序
	mpSort.sort(array,3,[](Person& x,Person& y){ return x.id>y.id; });
	cout<<"id升序:"<<endl;
	printArray(array,3);
	//第二次我想根据age排序
	cout<<"age升序:"<<endl;
	mpSort.sort(array,3,[](Person& x,Person& y){ return x.age>y.age; });
	printArray(array,3);
	delete p1;
	delete p2;
	delete p3;
	delete[] array;
	return 0;
}
sniffer12345 2014-03-08
  • 打赏
  • 举报
回复
引用 楼主 SmallYamateh 的回复:
我的需求是,想写一个泛型冒泡,来测试能否对任意class、任意策略进行排序; 这是Java代码,可以运行成功:



我在网上搜了好久,看到的都是“重载运算符”的冒泡,它的缺点就是不能第二次扩展;求高手贴代码给我!
汗,stl本身就有这个功能啊。。你填入不同的算子,自然能够进行针对不同字段的排序。另外,C++11有了lamba,直接就可以写了 sort(v.begin(), v.end(), [](const Foo& a, const Foo& b) { return a._i > b._i; });
ri_aje 2014-03-08
  • 打赏
  • 举报
回复
c++ 类似于 interface 的就是纯虚函数。

    virtual int compare(T *t1,T *t2) = 0;
最好别把 c++ 当 java 用,比如主楼的程序其实不用那么多设计模式的,搞几个函数就行了。

#include <algorithm>
#include <iostream>
#include <sstream>
using namespace std;

struct Person
{
    int id;
    int age;
    friend ostream& operator << (ostream& os, Person const& x)
    {
        return os << "{age:" << x.age <<",id:" << x.id << "}";
    }
};

int ageComp (Person const* const t1, Person const* const t2)
{
    return t1->age-t2->age;
}

int idComp (Person const* const t1, Person const* const t2)
{
    return t1->id-t2->id;
}

template <typename T, int N, typename C>
void sort (T (&array) [N], C&& comp)
{
    for(int i=0;i<N-1;i++)
    {
        for(int j=0;j<N-1-i;j++)
        {
            if (comp(array[j],array[j+1])>0)
            {
                using std::swap;
                swap(array[j],array[j+1]);
            }
        }
    }
}

template <typename T, size_t N>
void print_pointer_array (T const (&parray) [N])
{
    using std::begin;
    using std::end;
    std::for_each(begin(parray),end(parray),[](T const& t)
    {
        cout << *t <<endl;
    });
}

int main ()
{
    Person const persons [3]
    {
        {1,3},
        {2,2},
        {3,1},
    };

    Person const* pointers [3]
    {
        &persons[0],
        &persons[1],
        &persons[2],
    };

    cout<<"id asc:"<<endl;
    sort(pointers,idComp);
    print_pointer_array(pointers);

    cout<<"age asc:"<<endl;
    sort(pointers,ageComp);
    print_pointer_array(pointers);
}
kosora曹 2014-03-07
  • 打赏
  • 举报
回复
报这么个错误,我都不知道咋整: 1>01.obj : error LNK2019: 无法解析的外部符号 "public: int __thiscall MyComp<class Person>::compare(class Person *,class Person *)" (?compare@?$MyComp@VPerson@@@@QAEHPAVPerson@@0@Z),该符号在函数 "public: void __thiscall MpSort<class Person>::sort(class Person * *,int,class MyComp<class Person> *)" (?sort@?$MpSort@VPerson@@@@QAEXPAPAVPerson@@HPAV?$MyComp@VPerson@@@@@Z) 中被引用

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧