小编son*_*yao的帖子

为什么派生类不能通过指向base的指针访问其基类的受保护成员?

这是代码:

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++ inheritance scope protected

5
推荐指数
1
解决办法
310
查看次数

正确的朋友模板功能的语法

在"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; …

c++ templates friend

5
推荐指数
1
解决办法
878
查看次数

C++使用lambda进行隐式构造函数调用,期望函数指针

我试图从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)

c++ lambda language-lawyer c++11 c++14

5
推荐指数
1
解决办法
676
查看次数

C++中两个复制构造函数调用之间的区别是什么?

请看以下代码:

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

c++ initialization

5
推荐指数
1
解决办法
80
查看次数

对指针和constness兼容性的引用

出于学习目的,我编写了以下代码:

void Swap(const int *&Pointer1, const int *&Pointer2)
{
    const int *Tmp = Pointer2;
    Pointer2 = Pointer1;
    Pointer1 = Tmp;
}
Run Code Online (Sandbox Code Playgroud)

我对这段代码有一些疑问,以及在这种情况下顶级/低级constness如何工作,有3个或更多"级别".

  1. 显然我的引用不能是const,否则我将无法交换指针.但是假设代码不会触及指针值(它们包含的地址):正确的语法是const int*(const&Pointer)还是int*const&Pointer?我觉得后者的意思是"引用一个指向const int的const指针,但我不确定.如果是这样的话,编译器将忽略const部分,就像一个更简单的const int传递值或者不会,因为它是在参考?
  2. 尝试使用指向int的指针调用此函数失败.但是,可以为指向const int的指针分配一个int地址,如果我只删除引用,我确实没有错误.这让我觉得那些引用"强制"每个const完全匹配.这是真的?如果是这样,有一些方法吗?

c++ pointers const reference pass-by-reference

5
推荐指数
1
解决办法
135
查看次数

为什么在std :: move之后将成员unique_ptr &lt;&gt;保留为非空值?

当我将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++ exception unique-ptr move-semantics c++14

5
推荐指数
1
解决办法
68
查看次数

C++ countof 成员数组的实现

我正在尝试使用 C++ 模板创建与 Visual Studio _countof 宏等效的内容。以下是我建议的定义:

\n\n
template<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}\n
Run Code Online (Sandbox Code Playgroud)\n\n

上面的第二个声明是尝试修复以下代码,该代码在 g++ 9 中生成编译时错误,并显示消息:“错误:无效使用非静态数据成员 \xe2\x80\x98foo::bar\xe2\ x80\x99":

\n\n
struct foo {\n    int const bar[4];\n    static_assert(countof(bar) == 4);\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,当我添加第二个定义并将断言更改为 use 时foo::bar,g++ 生成错误:“错误:\xe2\x80\x98template constexpr const size_t countof\xe2\x80\x99 与先前的声明冲突”。

\n\n

我可以更改代码以使用指向成员的指针(而不是对成员的引用),但这似乎是不必要的。有谁知道一种方法来制作countof仅在传递数组时才编译的版本,并且以合理的方式适用于自由数组和成员变量数组?

\n

c++ templates g++ c++14

5
推荐指数
1
解决办法
688
查看次数

在右值参考参数上使用std :: move的原因

我正在读一本关于用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)

c++ rvalue-reference move-semantics c++11 value-categories

5
推荐指数
2
解决办法
106
查看次数

c ++用const参数而不是非常量参数覆盖虚函数

当我在写一个带有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)

c++ overriding constants signature

5
推荐指数
2
解决办法
330
查看次数

std::vector 中 push_back 函数的奇怪语法

我遇到了该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)

c++ initialization stdvector list-initialization

5
推荐指数
1
解决办法
95
查看次数