一道有意思的google面试题

deng2000 2007-05-08 11:58:19
今天看到一道google的面试题觉得挺有意思:

在C++文件中只declare class A, 但不以任何方式define class A, 是做什么用?
有兴趣的来讨论讨论
...全文
3255 65 打赏 收藏 转发到动态 举报
写回复
用AI写文章
65 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjlsmail 2008-03-19
  • 打赏
  • 举报
回复
Study
antterminator 2007-05-13
  • 打赏
  • 举报
回复
呵呵,谢谢,我还正郁闷不能这样写呢
确实是我写反了:
typedef typename _Find<T, typename L::rest>::value_type value_type;
-------------------------------------------------------------------
这样的话就可以避免很多不必要的东西了
deng2000 2007-05-13
  • 打赏
  • 举报
回复
哦,可能还需要加typename:
typedef typename _Find<T, typename L::rest>::value_type value_type;
deng2000 2007-05-13
  • 打赏
  • 举报
回复
惭愧,不知道C++标准中有整形值可以直接初始化这一条,呵呵
对,我说的typedef就是这个意思,但你好象写反了. 你可改成
typedef _Find<T, typename L::rest>::value_type value_type;
再试试
antterminator 2007-05-13
  • 打赏
  • 举报
回复
你说的typedef实现方法是这个意思吗?
template <class T, class L = PremierList>
struct _Find {
//static const bool value = _Find<T, typename L::rest>::value;
typedef value_type _Find<T, typename L::rest>::value_type;
};
这个我也考虑过,不过好像编译不过

好像C++标准规定整形值可以在类中直接初始化,当然bool也应该算是整形吧
:)
deng2000 2007-05-13
  • 打赏
  • 举报
回复
谢谢antterminator给的精彩例子.在这个mini Typelist中__class_type 确实不需要定义.
另外有个小建议, 把充斥其中的"static const bool value=..." 改成"typedef value_type ...".
后者更符合template习惯, 而且类静态变量就地赋值好象不是C++标准作法.
macwill 2007-05-13
  • 打赏
  • 举报
回复
暂时不懂
antterminator 2007-05-13
  • 打赏
  • 举报
回复
可以用于实现类似Loki中的TypeList,这里有一个简单的TypeList,只能用来判断一个类型T是build-in类型还是class类型:

typelist.h
--------------------------------------------------------------------------------
#ifndef TYPELIST_H
#define TYPELIST_H

template <class T, class U>
struct _TypeList {
typedef T first;
typedef U rest;
};

//struct __class_type {
//};
struct __class_type;

struct __true_type {
};

struct __false_type {
};

typedef _TypeList<char,
_TypeList<signed char,
_TypeList<unsigned char,
_TypeList<short,
_TypeList<unsigned short,
_TypeList<int,
_TypeList<unsigned int,
_TypeList<long,
_TypeList<unsigned long,
_TypeList<float,
_TypeList<double,
_TypeList<long double, __class_type> > > > > > > > > > > > PremierList;

template <class T, class L = PremierList>
struct _Find {
static const bool value = _Find<T, typename L::rest>::value;
};

template <class T, class U>
struct _Find<T, _TypeList<T, U>> {
static const bool value = true;
};

template <class T, class U>
struct _Find<T*, U> {
static const bool value = true;
};

template <class T, class U>
struct _Find<const T*, U> {
static const bool value = true;
};

template <int N, class U>
struct _Find<const char [N], U> {
static const bool value = true;
};

template <class T>
struct _Find<T, __class_type> {
static const bool value = false;
};

template <bool isPremier>
struct type_traits;

template <>
struct type_traits<true> {
typedef __true_type isPremier;
};

template <>
struct type_traits<false> {
typedef __false_type isPremier;
};

template <class T>
typename type_traits<_Find<T>::value>::isPremier
is_premier() {
return type_traits<_Find<T>::value>::isPremier();
}

#endif /*TYPELIST_H*/



typelist.cpp
-----------------------------------------------------------------------------
#include "typelist.h"
#include <iostream>
#include <string>

using namespace std;

template <class T>
void fun_impl(const T &s, __true_type) {
cout << "premier type :" << s << endl;
}

template <class T>
void fun_impl(const T &s, __false_type) {
cout << " class type :" << s << endl;
}

template <class T>
void fun(const T &s) {
fun_impl(s, is_premier<T>());
}

int main() {

int i = 100;
int &ri = i;
int *pi = &i;

fun(i);
fun(ri);
fun(pi);
fun(3.15);
fun("a c-style string");
fun(string("a std::string"));

return 0;
}
sinall 2007-05-12
  • 打赏
  • 举报
回复
robotom的例子确实不错。
就是句柄类的用法,这样做的话,在库和框架中都能应用得到。
deng2000 2007-05-11
  • 打赏
  • 举报
回复
老大,是你先给我提2.9节NullType的,我只是想把它弄清楚而已,怎么成了我纠缠不休了.
我说的还不够清楚吗,关于2.9节你受了侯捷中文版的误导了.
Aspist 2007-05-11
  • 打赏
  • 举报
回复
你还在跟我纠缠NullType,事实上2.9说得很清楚:
class NullType;
class EmptyType {};
确实Loki的源代码中是:class NullType {};但是我觉得class NullType;更好.这可以防止用户产生一个NullType对象.
"很明显,如果NullType没有定义的话,把它用到Typelist中肯定通不过编译."从这句话可以看出你还没有真正理解Typelist.
不要再跟我讨论NullType.请体会下面这句话:"光声明而没有定义类,只是告诉编译器有这样一个类型眯名称,仅此而已".
iceheart 2007-05-11
  • 打赏
  • 举报
回复
用做模块之间的接口
deng2000 2007-05-11
  • 打赏
  • 举报
回复
谢谢robotom,你给出的例子很有启发性.
不过,你的方案只是向库的使用者隐藏了类定义,A和MyClassInternal在库内部还是有定义的吧.我理想的情况是根本不需要定义的类, 象Th_Pk_Ying说的那种.
Th_Pk_Ying 2007-05-11
  • 打赏
  • 举报
回复
我的理解是可以用来区别有相同属性的不同模块或事物。

比如:
class _AudioModule;

class _VideoModule;

template<typename T>
struct SomeAttribute
{
// 这里是属性的一些数据
// 但是在这里并没有用到具体的类型T
}

typedef SomeAttribute<_AudioModule> AudioModule_Attribute
typedef SomeAttribute<_VideoModule> VideoModule_Attribute

也可以理解为定义一些类型吧

这里开始的两个类都是没有定义的,可能我的解释不是很清楚。
sinall 2007-05-11
  • 打赏
  • 举报
回复
哈哈,是我晕,不怪你。

各位看官,现在 nevergone 写出了第一种用途。
不知道上面的TypeList情况如何。。。
nevergone 2007-05-11
  • 打赏
  • 举报
回复
哦.
忘记写了. 不好意思 ^0^
那天是徒手写的

sinall 2007-05-11
  • 打赏
  • 举报
回复
好的,我晕啊,
上面的代码没有 class 关键字,我说怎么不能编译。。。
robotom 2007-05-11
  • 打赏
  • 举报
回复
以前常用的一个方式是:
class MyClassInternal;
class __declspec(dllimport) MyClass
{
public:
void do1();
void do2();

private:
MyClassInternal * m_internal;

};

这样这个类的内部实现给彻底隐藏了。
robotom 2007-05-11
  • 打赏
  • 举报
回复
下面是一个应用的地方:
class A;

class __declspec(dllimport) B
{
public:
void DoSomething( A * pA );

};
这里假设是B是一个导出类,想暴露类B,但是不想暴露跟B有关联的类A,可以在给客户的.h文件里使用这种方式的声明,让客户得以编译通过。在客户的工程中,任何地方都找不到类A的定义。


nevergone 2007-05-11
  • 打赏
  • 举报
回复
我给的代码当然不能编译啊.
给个完整的代码
#include <iostream>

using namespace std;

template <class T>
class Foo;

template <>
class Foo<int>
{
public:
Foo()
{
cout << "Foo<int>" << endl;
}
};

template <>
class Foo<char>
{
public:
Foo()
{
cout << "Foo<char>" << endl;
}
};

int main()
{
Foo<int> a;
Foo<char> b;
Foo<float> c;
return 0;
}
在我的g++下.编译的结果是:
$ g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:32: 错误: 聚合 ‘Foo<float> c’ 类型不完全,无法被定义
因为没有提供Foo<T>的定义.
注释那句Foo<float> c;
可以编译,我没有测试其他的编译器
加载更多回复(45)

64,654

社区成员

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

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