- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在开发一个小代码时遇到了一些问题。它本质上是一个几何库,我在其中为 3D 点定义了一个类,为 3D 表面定义了一个抽象类,然后我实现了不同的表面(平面、圆锥……)。该库是内置在模板中的(它必须是这样我才能在 ceres-solver 中使用它)。 MCVE这是:
点.h
#ifndef POINT_H
#define POINT_H
#include <iostream>
#include <memory>
template <typename T, int n>
class Surface;
template <typename T>
class Point
{
public:
typedef std::shared_ptr<Point<T>> Ptr;
typedef std::shared_ptr<const Point<T>> ConstPtr;
Point(T&& x, T&& y, T&& z)
{
data_[0] = x;
data_[1] = y;
data_[2] = z;
std::cout << "Point constructor" << std::endl;
}
Point(const T* data)
{
std::cout << "Cosntructor point from data ptr" << std::endl;
for (size_t i = 0; i < 4; i++)
data_[i] = data[i];
}
Point(const Point<T>& other) : Point(other.data_)
{
std::cout << "Constructor copy point" << std::endl;
}
~Point()
{
std::cout << "Point destructor" << std::endl;
}
template <int n>
T distance(const std::shared_ptr<const Surface<T, n>> surface) const
{
std::cout << "\n1: " << *this << std::endl;
ConstPtr a(this);
std::cout << "2: " << *this << std::endl;
T d = surface->distance(a);
std::cout << "3: " << *this << std::endl;
return d;
}
T& operator[](size_t i)
{
return data_[i];
}
T operator[](size_t i) const
{
return data_[i];
}
T& x()
{
std::cout << "x&" << std::endl;
return data_[0];
}
T& y()
{
return data_[1];
}
T& z()
{
return data_[2];
}
T x() const
{
return data_[0];
}
T y() const
{
return data_[1];
}
T z() const
{
return data_[2];
}
private:
T data_[3];
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const Point<T>& point)
{
os << "[";
for (size_t i = 0; i < 3; i++)
{
if (i != 0)
{
os << ",";
}
os << point[i];
}
os << "]";
return os;
}
#endif // POINT_H
表面.h
#ifndef SURFACE_H
#define SURFACE_H
#include <iostream>
#include <memory>
template <typename T>
class Point;
template <typename T, int n>
class Surface
{
public:
typedef std::shared_ptr<Surface<T, n>> Ptr;
typedef std::shared_ptr<const Surface<T, n>> ConstPtr;
Surface()
{
std::cout << "Surface constructor" << std::endl;
}
virtual ~Surface()
{
std::cout << "Surface destructor" << std::endl;
}
virtual T distance(const std::shared_ptr<const Point<T>> point) const = 0;
T& operator[](size_t i)
{
return data_[i];
}
T operator[](size_t i) const
{
return data_[i];
}
protected:
T data_[n];
};
#endif // SURFACE_H
plane.h
#ifndef PLANE_H
#define PLANE_H
#include "surface.h"
#include <math.h>
template <typename T>
class Point;
template <typename T>
class Plane : public virtual Surface<T, 4>
{
public:
typedef std::shared_ptr<Plane<T>> Ptr;
typedef std::shared_ptr<const Plane<T>> ConstPtr;
using Surface<T, 4>::data_;
Plane(T&& nx, T&& ny, T&& nz, T&& d)
{
data_[0] = nx;
data_[1] = ny;
data_[2] = nz;
data_[3] = d;
std::cout << "Plane constructor" << std::endl;
}
Plane(const T* data)
{
std::cout << "Cosntructor plane from data ptr" << std::endl;
for (size_t i = 0; i < 4; i++)
data_[i] = data[i];
}
Plane(const Plane<T>& other) : Plane(other.data_)
{
std::cout << "Constructor copy plane" << std::endl;
}
virtual ~Plane()
{
std::cout << "Plane destructor" << std::endl;
}
virtual T distance(const std::shared_ptr<const Point<T>> point) const override
{
return (data_[0] * point->x() + data_[1] * point->y() + data_[2] * point->z() - data_[3]) /
sqrt(pow(data_[0], 2) + pow(data_[1], 2) + pow(data_[2], 2));
}
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const Plane<T>& plane)
{
os << plane[0] << "*x+" << plane[1] << "*y+" << plane[2] << "*z = " << plane[3];
return os;
}
#endif // PLANE_H
主要
#include "plane.h"
#include "point.h"
int main()
{
Point<float>::Ptr point(new Point<float>(100, 100, 1.6));
Plane<float>::Ptr plane(new Plane<float>(1, 2, 3, -10));
float d1 = plane->distance(point);
std::cout << "Distance from " << *point << " to " << *plane << " -> " << d1 << std::endl;
std::cout << "Point " << *point << "; Plane " << *plane << std::endl;
float d2 = point->distance<4>(plane);
std::cout << "Distance from " << *point << " to " << *plane << " -> " << d2 << std::endl;
std::cout << "Point " << *point << "; Plane " << *plane << std::endl;
return 0;
}
这会产生正确的距离输出。但是,如果我使用 Point::distance
方法x
和 y
该点的值更改为 0
而如果我使用 Plane::distance
, x
和 y
一点都没有改变。在这两种情况下都是 distance
方法是 const 并作为输入 const std::shared_ptr<const Plane<T>>
和 const std::shared_ptr<const Point<T>>
.
我的问题:如果所有内容都设置为 const
,那么 Point 的值怎么可能改变? ?
我知道当 ConstPtr a(this)
时会发生这种情况在 Point::distance
被破坏了,但我什至不知道使用哪个构造函数来创建 ConstPtr a(this)
在Ponit::distance
方法。
程序的输出是:
Point constructor
Surface constructor
Plane constructor
Distance from [100,100,1.6] to 1*x+2*y+3*z = -10 -> 84.1338
Point [100,100,1.6]; Plane 1*x+2*y+3*z = -10
1: [100,100,1.6]
2: [100,100,1.6]
3: [100,100,1.6]
Point destructor
Distance from [0,0,1.6] to 1*x+2*y+3*z = -10 -> 84.1338
Point [0,0,1.6]; Plane 1*x+2*y+3*z = -10
Plane destructor
Surface destructor
Point destructor
最佳答案
问题出在ConstPtr a(this);
- 这一行创建一个 std::shared_ptr
取得当前对象的所有权和 delete
超出范围后就可以了。
因此 point
在调用 float d2 = point->distance<4>(plane);
之后指针变成了一个悬挂指针并取消引用它会导致未定义的行为
为了解决问题 Point
类需要继承自 std::enable_shared_from_this
和行 ConstPtr a(this);
需要变成ConstPtr a(shared_from_this());
关于c++ - const std::shared_ptr<const T> 作为函数的参数最终会改变智能指针中类的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51921410/
我对这个错误很困惑: Cannot implicitly convert type 'System.Func [c:\Program Files (x86)\Reference Assemblies\
考虑这段代码: pub trait Hello { fn hello(&self); } impl Hello for Any { fn hello(&self) {
问题很简单。是否可以构造这样一个类型 T,对于它下面的两个变量声明会产生不同的结果? T t1 = {}; T t2{}; 我已经研究 cppreference 和标准一个多小时了,我了解以下内容:
Intellij idea 给我这个错误:“Compare (T, T) in Comparator cannot be applied to (T, T)” 对于以下代码: public class
任何人都可以告诉我 : n\t\t\t\t\n\t\t\t 在以下来自和 dwr 服务的响应中的含义和用途是什么. \r\n\t\t\t \r\n\t\t\t
让 T 成为一个 C++ 类。 下面三个指令在行为上有什么区别吗? T a; T a(); T a = T(); T 为不带参数的构造函数提供了显式定义这一事实是否对问题有任何改变? 后续问题:如果
Rust中的智能指针是什么 智能指针(smart pointers)是一类数据结构,是拥有数据所有权和额外功能的指针。是指针的进一步发展 指针(pointer)是一个包含内存地
比如我有一个 vector vector > v={{true,1},{true,2},{false,3},{false,4},{false,5},{true,6},{false,7},{true,8
我有一个来自 .xls 电子表格的数据框,我打印了 print(df.columns.values) 列,输出包含一个名为:Poll Responses\n\t\t\t\t\t。 我查看了 Excel
This question already has answers here: What are good reasons for choosing invariance in an API like
指针类型作为类型前缀与在类型前加斜杠作为后缀有什么区别。斜线到底是什么意思? 最佳答案 语法 T/~ 和 T/& 基本上已被弃用(我什至不确定编译器是否仍然接受它)。在向新向量方案过渡的初始阶段,[T
我正在尝试找到一种方法来获取模板参数的基类。 考虑以下类: template class Foo { public: Foo(){}; ~Foo(){};
这是一个让我感到困惑的小问题。我不知道如何描述它,所以只看下面的代码: struct B { B() {} B(B&) { std::cout ::value #include
为什么有 T::T(T&) 而 T::T(const T&) 更适合 copy ? (大概是用来实现move语义的???) 原始描述(被melpomene证明是错误的): 在C++11中,支持了一种新
在 Java 7 中使用 eclipse 4.2 并尝试实现 List 接口(interface)的以下方法时,我收到了警告。 public T[] toArray(T[] a) { ret
假设有三个函数: def foo[T](a:T, b:T): T = a def test1 = foo(1, "2") def test2 = foo(List(), ListBuffer()) 虽
我对柯里化(Currying)和非柯里化(Currying)泛型函数之间类型检查的差异有点困惑: scala> def x[T](a: T, b: T) = (a == b) x: [T](a: T,
考虑一个类A,我如何编写一个具有与相同行为的模板 A& pretty(A& x) { /* make x pretty */ return x; } A pretty(A&& x) {
Eclipse 表示由于泛型类型橡皮擦,类型参数不允许使用 instanceof 操作。 我同意在运行时不会保留任何类型信息。但是请考虑以下类的通用声明: class SomeClass{ T
在 C++14 中: 对于任何整数或枚举类型 T 以及对于任何表达式 expr: 有没有区别: struct S { T t { expr }; }; 和 struct S { T t = { exp
我是一名优秀的程序员,十分优秀!