这是代码:
class TestA
{
protected:
int test=12;
public:
TestA() {
cout << "test a: " << test << endl;
}
~TestA() {
}
};
class TestB : public TestA
{
public:
TestB(TestA *testA) {
cout << "test b: " << testA->test;
}
~TestB() {
}
};
int main ()
{
TestA *pTestA=new TestA();
TestB *pTestB=new TestB(pTestA);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试protected使用指向TestA类型对象的指针(因此,实例TestA)来访问成员.TestB也来源于TestA
为什么我无法访问它?它只能在我需要它的类中"访问"吗?不在外面使用指针/直接声明?
在"C++编程语言"第四版 - 第23.4.7章"朋友"中,我找到了以下示例(我稍微修改了它以仅显示相关部分):
template<typename T>
class Vector {
public:
friend Vector operator*<>(const Vector& v, int f);
^^ ~~~~ ?
};
template<typename T>
Vector<T> operator*(const Vector<T>& v, int f) {
return v;
}
Run Code Online (Sandbox Code Playgroud)
我试图编译它,但我得到以下错误(clang):
main.cpp:8:20: error: friends can only be classes or functions
friend Vector operator*<>(const Vector& v, int f);
^
main.cpp:8:29: error: expected ';' at end of declaration list
friend Vector operator*<>(const Vector& v, int f);
^
;
2 errors generated.
Run Code Online (Sandbox Code Playgroud)
书解释说:
需要友元函数名称后面的<>来表明朋友是模板函数.如果没有<>,则假定为非模板函数.
这就是全部.
如果没有<>此代码编译,但在使用operator*时(例如Vector<int> v; v*12; …
我试图从lambda函数隐式构造一个对象.对象的构造函数将函数指针作为参数.但是代码[1]不能使用以下消息进行编译:
6 : <source>:6:5: note: candidate constructor not viable: no known conversion from '(lambda at /tmp/compiler-explorer-compiler117117-54-dfxyju.lkw98/example.cpp:22:14)' to 'Bar' (aka 'bool (*)()') for 1st argument
Foo(Bar b) : m_b{b} {}
Run Code Online (Sandbox Code Playgroud)
但是标准规定lambda函数可以隐式转换为具有相同参数和返回类型的函数指针[2].这应该适用于此,因此我希望构造函数可以调用.
那么代码为什么不编译呢?谢谢你的解释!
[1]代码示例:
using Bar = bool(*)();
class Foo
{
public:
Foo(Bar b) : m_b{b} {}
private:
Bar m_b;
};
int main()
{
// working
Foo f1 ( [](){ return true; });
Foo f2 = Bar( [](){ return true; });
// working implicit conversion
bool(*tmp)() = []() { return true; }; …Run Code Online (Sandbox Code Playgroud) 请看以下代码:
class Foo
{
public:
Foo(){}
explicit Foo(const Foo &){}
};
int main()
{
Foo foo1;
Foo foo2(foo1);
Foo foo3 = foo1; //can not compile
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么Foo foo3 = foo1;无法编译,两个复制构造函数调用之间有什么区别?
ps:我的编译器工具是GCC4.8.2
出于学习目的,我编写了以下代码:
void Swap(const int *&Pointer1, const int *&Pointer2)
{
const int *Tmp = Pointer2;
Pointer2 = Pointer1;
Pointer1 = Tmp;
}
Run Code Online (Sandbox Code Playgroud)
我对这段代码有一些疑问,以及在这种情况下顶级/低级constness如何工作,有3个或更多"级别".
当我将a unique_ptr<>移入引发的函数中时,move -from指针不为空。这是正常现象吗?
这是两个显示该行为的测试程序。我可以在类的析构函数中观察到唯一的指针:
#include <memory>
#include <iostream>
void f(std::unique_ptr<int> &&) { throw "fail"; }
struct except_move_tester
{
std::unique_ptr<int> x;
except_move_tester()
: x(std::make_unique<int>(0))
{}
~except_move_tester() { std::cout << "x at destructor: " << x.get() << std::endl; }
void g()
{
std::cout << "x at g: " << x.get() << std::endl;
f(std::move(x));
}
};
int main()
{
try {
except_move_tester t;
t.g();
} catch (...) {}
}
Run Code Online (Sandbox Code Playgroud)
运行时给出的输出:
x at g: 0x7f818b402ac0
x at destructor: 0x7f818b402ac0
Run Code Online (Sandbox Code Playgroud)
如果我按如下方式修改上面的清单(只是在函数调用的位置添加了一个临时名称),那么我通常会期望得到异常安全行为:
#include <memory>
#include …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 C++ 模板创建与 Visual Studio _countof 宏等效的内容。以下是我建议的定义:
\n\ntemplate<typename T, size_t N>\ninline constexpr size_t countof(T const (&array)[N]) {\n return N;\n}\ntemplate<typename T, typename U, size_t N>\ninline constexpr size_t countof(T const (U::&array)[N]) {\n return N;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n上面的第二个声明是尝试修复以下代码,该代码在 g++ 9 中生成编译时错误,并显示消息:“错误:无效使用非静态数据成员 \xe2\x80\x98foo::bar\xe2\ x80\x99":
\n\nstruct foo {\n int const bar[4];\n static_assert(countof(bar) == 4);\n};\nRun Code Online (Sandbox Code Playgroud)\n\n但是,当我添加第二个定义并将断言更改为 use 时foo::bar,g++ 生成错误:“错误:\xe2\x80\x98template constexpr const size_t countof\xe2\x80\x99 与先前的声明冲突”。
我可以更改代码以使用指向成员的指针(而不是对成员的引用),但这似乎是不必要的。有谁知道一种方法来制作countof仅在传递数组时才编译的版本,并且以合理的方式适用于自由数组和成员变量数组?
我正在读一本关于用C ++实现的数据结构的书,我不明白代码片段吗?它是向量类的一部分
void push_back(object &&x) {
//do something
objects[size++] = std::move(x);
}
Run Code Online (Sandbox Code Playgroud)
我知道std::move返回对象的右值引用,但是push_back成员函数已经具有右值引用x作为参数,std::move这里不是不必要的吗?
另一个问题是,如果我们有一个类对象的右值引用,std::move如果要调用move而不是copy right 还是需要在其成员上使用它?像下面的代码:
A& operator=(A&& other) {
member = std::move(other.member);
return *this;
}
Run Code Online (Sandbox Code Playgroud) 当我在写一个带有const参数而不是非常量参数的overide函数时,我以为编译器会报错,因为base函数有非常量参数,但是编译成功了。为什么?
我的代码:
#include <iostream>
class A
{
public:
virtual uint64_t cal(uint64_t value)
{
std::cout << value << std::endl;
return value;
}
};
class B : public A
{
public:
uint64_t cal(const uint64_t value) override;
};
uint64_t B::cal(const uint64_t value)
{
std::cout << value + 1 << std::endl;
return (value+1);
}
int main()
{
B b;
b.cal(1);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我遇到了该push_back函数的以下语法。Vertex只是一个包含三个浮点数 x、y 和 z 的结构。第二行看起来就像会写它。但是第一行对我来说看起来很奇怪。在解释这一点的视频中,据说这是通过成员初始值设定项列表完成的,但它看起来更像是隐式转换。我只是对那里的大括号感到困惑。谁能解释为什么这种语法有效?
std::vector<Vertex> vertices;
vertices.push_back({ 1, 2, 3 });
vertices.push_back(Vertex(1, 2, 3));
Run Code Online (Sandbox Code Playgroud)