我有几个问题。
类成员中的所有函数都是函数吗?或只有声明“朋友”之前的那些?
成员函数的意义在于,任何其他类都无法访问它们吗?
隐式和显式调用之间有什么区别?
可以或不可以隐式调用哪些函数?
我希望看到一个隐式和显式调用的例子。
编辑:感谢您的回答,有很多点点滴滴回答了我的问题并感谢书中的链接。我会读他们的。
答案 0 :(得分:7)
阅读Thinking in C++ by Bruce Eckel。这是一本优秀,非常易读的电子书,可以免费下载,并将回答您的所有问题。
答案 1 :(得分:4)
隐式调用构造函数,析构函数和operator type()
函数。
答案 2 :(得分:3)
我认为一个好的开始就是阅读这个网站:The C++ FAQ。
但是,简要回答一下:在类定义中声明的所有函数和变量都是该类的成员。 “friend”关键字具有与谁可以访问各个成员有关的特殊含义。
访问权限由成员是否已在类定义的公共,私有或受保护部分声明来控制。
阅读C ++常见问题解答可以让您了解这些内容如何组合在一起。
答案 3 :(得分:3)
所有函数都在一个类中 会员职能?或者只是那些 之前是声明“朋友”?
朋友功能不是会员功能。它们与常规全局函数的不同之处在于它们可以访问该类的非公共区域。例如:
class myclass
{
friend void fun(const myclass& obj);
int x;
};
void fun(const myclass& obj)
{
std::cout << obj.x; // x is private member
}
有什么区别 隐式和显式调用?
使用() operator
调用函数时,它是显式调用。如果你不这样做,那就是隐含的。显式调用的示例:
fun();
隐式调用的示例:
void someScope(){
myclass myobject; // constructors called
} // destructor of myobject is called before exiting the function
....
myclass* mySecondObject = new myclass; // constructor called
delete mySecondObject; // destructor called
答案 4 :(得分:3)
隐式和显式调用函数之间存在细微差别。请考虑标准文档中的以下测试用例
struct A { };
void operator + (A, A);
struct B {
void operator + (B);
void f ();
};
A a;
void B::f() {
operator+ (a,a); // ERROR – global operator hidden by member
a + a; // OK – calls global operator+
}
第一个失败是因为你明确地给了一个函数名,并且名字将被“内向外”查找:首先在函数中,然后在它的类中,然后在全局范围内。
在第二个中,函数候选者的查找工作方式不同:成员和非成员函数分两个阶段查找,当查找非成员函数时,成员函数被忽略,因此成员操作符不会隐藏第二种情况下的全球运营商。
显式函数调用也永远不会选择内置运算符。例如,你不能operator+(10, 12);
。一般来说,我总是喜欢隐式函数调用。
类成员中的所有函数都是函数吗?或者只有声明“朋友”之前的那些?
正如其他人所说,友元函数不是包含声明的类的成员,即使函数也在声明中定义
struct A {
friend void f() {
std::cout << "member of the global namespace" << std::endl;
}
void g() {
std::cout << "member of class A" << std::endl;
}
};
f
的词汇范围是A
- 这意味着您可以引用(静态)成员或A
的嵌套类型,而不会在A::
之前使用其名称。< / p>
关于特殊成员函数,可以显式调用析构函数或赋值运算符,而不能显式调用构造函数。他们的调用是隐含的,并且是创建新对象的一部分。
答案 5 :(得分:0)
类成员中的所有函数都是函数吗?这取决于你的意思 “内”。您可以在类命名空间中定义独立(非成员)函数。 声明为“朋友”的函数是不是成员函数(如果是,则不需要将它们声明为朋友)。类定义中的非友元函数是成员函数。
具有“公共”访问权限的成员函数可由其他类和独立函数访问。
隐式函数调用通常出现在类型转换和对象构造的上下文中。这是一个example:
class BigBuffer
{
public:
BigBuffer(int initialValue)
{ memset(buffer, initialValue, sizeof(buffer)); }
private:
char buffer[65536];
};
extern void Foo(const BigBuffer& o);
void oops()
{
Foo(3);
}
Foo(3)导致对BigBuffer构造函数的隐式调用以转换 整数3到Foo函数期望的BigBuffer对象中。
答案 6 :(得分:0)
回答问题:
类声明中的所有函数都是成员函数,标记为“friend”的函数除外。这些是可以访问内部的其他类或函数 有问题的课程。
成员函数是执行与类相关的功能的函数。它们默认为private
,或者如果它们位于private:
指示符之后,则意味着它们只能由类中的其他函数访问。其他访问修饰符是protected
,这意味着它们可以被其他类函数和继承自此类的类中的函数访问,并且public
,这意味着它们对于每个人来说都是公平的游戏。指定为friend
的类或函数可以访问private
和protected
数据和函数成员。
我不清楚隐含和明确的含义。一个可能的含义与explicit
关键字有关,可以应用于构造函数。
在Foo课堂上,假设我宣布
Foo(int i);
explicit Foo(const char * s);
这意味着,如果我在某处提到一个int值,编译器就可以将它视为Foo,但为了将字符串视为一个值,我必须明确它,所以如果我有
f(Foo f);
在某处宣布,然后
f(1);
f(Foo("foo"));
是合法的电话,但是
f("foo");
不是
从问题的本质来看,我会说你需要一本好的小学C ++书。除了excellent C++ books之外,还有一个关于我C++ FAQ Lite的StackOverflow问题。你可以通过学习课程和在这里提出随机问题来学习,但这需要更长时间,你会错过任何事情。
答案 7 :(得分:0)
显式表示只有在源代码中专门调用该函数时才会调用该函数。
大多数情况下,它与构造函数一起使用,以防止编译器在创建临时或转换时使用特定的构造函数。
例如:
class FooA
{
public:
FooA();
};
class FooB
{
public:
FooB();
explicit FooB(const FooA &other);
};
现在假设你有这个功能:
void MyFunc(FooB &var) { ... }
和此代码
void main()
{
FooA bar;
MyFunc(bar);
FooB foo(bar);
}
通常,如果您没有“explicit”关键字,编译器将能够通过构造函数从FooB类型构造FooA类型。现在它会抱怨当你将它传递给MyFunc()时它不知道如何从fooB制作一个FooA。
然而,它不会抱怨因为你明确地调用了它来构建foo。
答案 8 :(得分:-1)
不确定隐含和明确的含义......
默认情况下,类成员是私有的。添加好友规范允许另一个类访问私有成员。例如:
class A
{
void hidden();
friend class B;
};
class B
{
void callIntoA( A& a )
{
a.hidden();
}
};
或者,如果您想公开某些内容,可以按如下方式指定“public:”部分:
class A
{
void hidden();
public:
void notHidden();
void alsoNotHidden();
private:
void alsoHidden();
};